如何在Swing中实现动态GUI

首先,为发布一些过分具体的内容而道歉,但是我对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());

}

}`

以上是 如何在Swing中实现动态GUI 的全部内容, 来源链接: utcz.com/qa/407654.html

回到顶部