Как реализовать динамический графический интерфейс в качелях

Прежде всего, извинения за публикацию чего-то, возможно, немного чрезмерно специфичны, но я не очень опытен с Swing и не могу найти хороших примеров, которые бы соответствовали моим потребностям.

Поэтому я пытаюсь найти лучший способ реализации динамического GUI для выбора критериев фильтрации в Swing:

Макет GUI для реализации

Основная модель – это class, содержащий список критериев, которые могут быть сведены на нет (т. Е. Применены с помощью NOT-префикса) и свойство, указывающее, должны ли они быть объединены с AND или OR.

GUI позволит пользователю добавлять, изменять или удалять критерии и выбирать оператор комбинации (и / или). У первого критерия, естественно, не было бы комбинационного селектора, а третий и последующий критерии просто использовали бы тот же самый комбинационный оператор, что и второй.

X-кнопки справа будут использоваться для удаления критерия. При нажатии кнопки «Add» добавляется новая строка компонентов. По мере внесения изменений они будут отражены в базовой модели.

Конечно, я мог бы реализовать это довольно «примитивно», просто добавив компоненты в JPanel, а затем обновив модель соответственно, но я предпочел бы более аккуратное решение, такое как предоставленное TableModel.

Поэтому мне интересно, будет ли таблица с пользовательским TableModel и TableCellRenderer / Editor наилучшим подходом, или если есть лучший способ реализовать что-то вроде этого. Если таблица действительно лучший подход, я был бы признателен за некоторые указания на то, как можно использовать TableCellRenderers или -Editors для достижения этого.

Заранее спасибо.

только пример, все жестко запрограммировано, для хорошего понимания

РЕДАКТИРОВАТЬ:

как заметил 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 – лучший выбор. http://download.oracle.com/javase/tutorial/uiswing/components/table.html Это было бы хорошо начать.

добавьте все компоненты для критериев поиска на панель и добавьте / удалите конкретную панель. Я не думаю, что Tablemodel – хороший выбор здесь.

Netbeans имеет хороший ui, который делает что-то похожее на то, что вы описываете: Фильтр ключевых слов

Почему бы не встать на плечи гигантов? Панели Netbeans выглядят хорошо и хорошо работают. Реализация даже чисто разделена между ui и кодом модели. Если бы я был на вашем месте (и это был июнь 2011 года), я бы основал свое решение на источнике здесь:

http://hg.netbeans.org/main/file/14d339767aef/tasklist.ui/src/org/netbeans/modules/tasklist/filter

KeywordPanel.java содержит этот критический комментарий: «GUI основан на том, что в почтовом ящике Mozilla».

Интересно, что это может быть?

Извините за столь поздний ответ.

  • Hamcrest сравнить коллекции
  • Изменение имен параметризованных тестов
  • Selenium WebDriver - проверка наличия элемента
  • Обнаружить и извлечь url из строки?
  • Если не использовать Regex в C # (или Java, C ++ и т. Д.),
  • Java: parse java исходный код, методы извлечения
  • Возвращает несколько значений из метода Java: почему нет объектов n-кортежей?
  • Должны ли JDBC-результаты и заявления быть закрыты отдельно, хотя соединение закрывается впоследствии?
  • Как анализировать содержимое PermGen?
  • Javamail Не удалось преобразовать сокет в TLS GMail
  • Как я могу справиться со сканером (java)?
  • Давайте будем гением компьютера.