当前位置: 首页 > 面试题库 >

如何在Swing中实现动态GUI

欧阳哲
2023-03-14
问题内容

首先,为发布一些过分具体的内容而道歉,但是我对Swing并不十分了解,并且似乎找不到适合我需求的好例子。

因此,我试图找出实现动态GUI以便在Swing中选择过滤条件的最佳方法:

要实现的GUI样机

基础模型是一个类,其中包含可否定(例如,使用NOT前缀)条件的列表,以及指示这些条件应与AND还是OR组合的属性。

GUI将允许用户添加,更改或删除条件,并选择组合运算符(和/或)。第一个条件自然不会具有组合选择器,而第三个条件和后续条件将仅使用与第二个条件相同的组合操作符。

右侧的X按钮将用于删除条件。当按下添加按钮时,新的组件行将被添加到底部。进行更改时,这些更改将反映在基础模型中。

当然,我可以通过简单地将组件添加到JPanel然后相应地更新模型来“非常原始地”实现此功能,但是我更喜欢更整洁的解决方案,例如TableModel提供的解决方案。

因此,我想知道带有自定义TableModel和TableCellRenderer / Editor的表是否是最佳方法,或者是否有更好的方法来实现类似的方法。如果table确实是最好的方法,我将对使用TableCellRenderers或-Editors如何完成此工作的一些指示表示赞赏。

提前致谢。


问题答案:

仅作为示例,所有内容都经过硬编码,以更好地理解

编辑:

正如kleopatra所注意到的那样,将JTable#fireTableDataChanged()从ActionListener移到了TableModel,修改了所有ClassName以lowerCase开头

`import java.awt.;
import java.awt.event.
;
import java.util.EventObject;
import javax.swing.;
import javax.swing.table.
;

public class ComponentTableTest {

private JFrame frame;
private JTable CompTable = null;
private CompTableModel CompModel = null;
private JButton addButton = null;

public static void main(String args[]) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            new ComponentTableTest().makeUI();
        }
    });
}

public void makeUI() {
    CompTable = CreateCompTable();
    JScrollPane CompTableScrollpane = new JScrollPane(CompTable, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
            JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
    JPanel bottomPanel = CreateBottomPanel();
    frame = new JFrame("Comp Table Test");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(CompTableScrollpane, BorderLayout.CENTER);
    frame.add(bottomPanel, BorderLayout.SOUTH);
    frame.setPreferredSize(new Dimension(800, 400));
    frame.setLocation(150, 150);
    frame.pack();
    frame.setVisible(true);
}

public JTable CreateCompTable() {
    CompModel = new CompTableModel();
    CompModel.addRow();
    JTable table = new JTable(CompModel);
    table.setRowHeight(new CompCellPanel().getPreferredSize().height);
    table.setTableHeader(null);
    CompCellEditorRenderer compCellEditorRenderer = new CompCellEditorRenderer();
    table.setDefaultRenderer(Object.class, compCellEditorRenderer);
    table.setDefaultEditor(Object.class, compCellEditorRenderer);
    return table;
}

public JPanel CreateBottomPanel() {
    addButton = new JButton("Add Comp");
    addButton.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent ae) {
            Object source = ae.getSource();

            if (source == addButton) {
                CompModel.addRow();
                //CompModel.fireTableDataChanged(); // moved to TableModel
            }
        }
    });
    JPanel panel = new JPanel(new GridBagLayout());
    panel.add(addButton);
    return panel;
}

}

class CompCellEditorRenderer extends AbstractCellEditor implements TableCellRenderer, TableCellEditor {

private static final long serialVersionUID = 1L;
private CompCellPanel renderer = new CompCellPanel();
private CompCellPanel editor = new CompCellPanel();

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    renderer.setComp((Comp) value);
    return renderer;
}

@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
    editor.setComp((Comp) value);
    return editor;
}

@Override
public Object getCellEditorValue() {
    return editor.getComp();
}

@Override
public boolean isCellEditable(EventObject anEvent) {
    return true;
}

@Override
public boolean shouldSelectCell(EventObject anEvent) {
    return false;
}

}

class CompTableModel extends DefaultTableModel {

private static final long serialVersionUID = 1L;

@Override
public int getColumnCount() {
    return 1;
}

public void addRow() {
    super.addRow(new Object[]{new Comp(0, 0, "", "")});
    //super.fireTableDataChanged();
}

}

class Comp {

int type;
int relation;
String lower;
String upper;

public Comp(int type, int relation, String lower, String upper) {
    this.type = type;
    this.relation = relation;
    this.lower = lower;
    this.upper = upper;
}

}

class CompCellPanel extends JPanel {

private static final long serialVersionUID = 1L;
private JLabel labelWith = new JLabel("With ");
private JComboBox typeCombo = new JComboBox(new Object[]{"height", "length", "volume"});
private JComboBox relationCombo = new JComboBox(new Object[]{"above", "below", "between"});
private JTextField lowerField = new JTextField();
private JLabel labelAnd = new JLabel(" and ");
private JTextField upperField = new JTextField();
private JButton removeButton = new JButton("remove");

CompCellPanel() {
    setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
    relationCombo.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            enableUpper(relationCombo.getSelectedIndex() == 2);
        }
    });
    enableUpper(false);
    removeButton.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            JTable table = (JTable) SwingUtilities.getAncestorOfClass(JTable.class, (Component) e.getSource());
            int row = table.getEditingRow();
            table.getCellEditor().stopCellEditing();
            ((DefaultTableModel) table.getModel()).removeRow(row);
        }
    });
    add(labelWith);
    add(typeCombo);
    add(relationCombo);
    add(lowerField);
    add(labelAnd);
    add(upperField);
    add(Box.createHorizontalStrut(100));
    add(removeButton);
}

private void enableUpper(boolean enable) {
    labelAnd.setEnabled(enable);
    upperField.setEnabled(enable);
}

public void setComp(Comp Comp) {
    typeCombo.setSelectedIndex(Comp.type);
    relationCombo.setSelectedIndex(Comp.relation);
    lowerField.setText(Comp.lower);
    upperField.setText(Comp.upper);
    enableUpper(Comp.relation == 2);
}

public Comp getComp() {
    return new Comp(typeCombo.getSelectedIndex(), relationCombo.getSelectedIndex(), lowerField.getText(), upperField.getText());
}

}`



 类似资料:
  • 我正在测试一些使用JWindow和隐藏jframe的代码,所以我必须创建最小化、最大化和关闭按钮,以方便用户使用。单击创建的按钮时,如何将状态设置为帧。

  • 让我,如果你有谁回答,这是。基本上需要像谷歌搜索引擎,当我们按下任何一个键然后它就会显示建议相关的按下键。 尊敬Satish Dhiman

  • 问题内容: 我需要动态添加组件。此外,我需要动态更改布局。 问题答案: 作为参考,以下是显示基本方法的脚本validate()。这个更精致的示例显示了两个要求:它更改布局并动态添加组件。

  • 问题内容: 我有兴趣在JFrame中提供自动补全框。触发机制将基于助记符(我认为),但是我不太确定“自动补全框”应使用什么(我希望在用户按下键时对结果进行过滤)。 您将如何实施?某种JFrame还是JPopupMenu? 我想知道这是如何实现的,所以请不要发布指向可用的[J] Components的链接。 问题答案: Sun的教程“使用Swing组件”中提供了 一个自动完成文本区域 的示例 。 它

  • 本文向大家介绍如何在JavaScript中实现多态?,包括了如何在JavaScript中实现多态?的使用技巧和注意事项,需要的朋友参考一下 多态性 多态 是面向对象编程(OOP)的宗旨之一。它有助于设计对象,使其可以与特定提供的对象共享或覆盖任何行为。多态性 利用继承的 优势来实现这一点。 在以下示例中,子对象(例如“板球”和“网球”)已覆盖从父对象“游戏”调用的“选择”方法,并分别返回了新字符串

  • 结果一点都不顺利,你有什么建议吗?