问题描述
|
首先,为发布一些过分具体的内容而道歉,但是我对Swing不太了解,并且似乎找不到适合我需求的好例子。
因此,我试图找出实现动态GUI以便在Swing中选择过滤条件的最佳方法:
基础模型是一个类,其中包含可否定的条件列表(即使用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,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,\"\",\"\")});
//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是最佳选择。
http://download.oracle.com/javase/tutorial/uiswing/components/table.html
那将是很好的开始。
, 将搜索条件的所有组件添加到面板中,然后添加/删除特定的面板。我认为Tablemodel在这里不是一个好的选择。
, Netbeans有一个不错的ui,它的功能类似于您所描述的:
为什么不站在巨人的肩膀上呢? Netbeans面板看起来不错并且运行良好。实现甚至在ui和模型代码之间完全分开。如果我正穿上鞋子(那是2011年6月),我的解决方案将基于以下来源:
http://hg.netbeans.org/main/file/14d339767aef/tasklist.ui/src/org/netbeans/modules/tasklist/filter
KeywordPanel.java包含以下神秘注释:\“ GUI基于Mozilla邮件工具中的GUI \”。
我不知道那会是什么?
抱歉回复晚了。