如何在swing中实现dynamicGUI
首先,对于发布某些东西可能有点过分的道歉,但我对Swing并不是很有经验,似乎也找不到符合我需求的好例子。
所以我试图找出实现dynamicGUI的最佳方式,以便在Swing中select过滤条件:
基础模型是一个包含可以被否定的标准列表的类(即,应用NOT-前缀)以及指示这些标准是否应该与AND或OR组合的属性。
GUI将允许用户添加,更改或删除条件,并select组合运算符(和/或)。 第一个标准自然不会有一个组合select器,第三个和后续的标准将简单地使用与第二个标准相同的组合运算符。
右侧的Xbutton将用于删除标准。 当按下添加button时,一行新的组件将被添加到底部。 随着变化,这些将反映在基础模型中。
当然,我可以通过简单地将组件添加到一个JPanel然后相应地更新模型来实现这个function,但是我更喜欢一个整洁的解决scheme,比如TableModel提供的解决scheme。
所以我想知道如果一个自定义TableModel和TableCellRenderer /编辑器的表是最好的方法,或者如果有更好的方式来实现这样的事情。 如果表确实是最好的方法,我将不胜感激指望如何使用TableCellRenderers或 – 编辑来实现这一点。
提前致谢。
只是例子,一切都是硬编码的,为了好的理解
编辑:
正如kleopatra的注意到的那样,将JTable#fireTableDataChanged()从ActionListener移动到TableModel,修改了所有ClassNames以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()); } }
我觉得这样一个自定义的TableMOdel和TableCellRenderer / Editor是最好的select。 http://download.oracle.com/javase/tutorial/uiswing/components/table.html这将是很好的开始。;
将所有search条件的组件添加到面板并添加/删除特定的面板。 我不认为桌面模型在这里是一个好的select。
Netbeans有一个很好的用户界面,它与你所描述的类似:
为什么不站在巨人的肩膀上呢? Netbeans面板看起来不错,工作得很好。 UI和模型代码之间的实现甚至干净地分开。 如果我在你的鞋子里(现在是2011年6月份),我会把我的解决scheme放在源代码的基础上:
http://hg.netbeans.org/main/file/14d339767aef/tasklist.ui/src/org/netbeans/modules/tasklist/filter
KeywordPanel.java包含了这个神秘的评论:“GUI基于Mozilla的邮件工具。”
我想知道这可能是什么?
抱歉回复晚了。