2010-12-24 3 views
3

У меня есть JTable, у которого есть один столбец, который не редактируется, а второй столбец - это флажок, который отображает логические значения .... Теперь я хочу, когда пользователь выбирает несколько строк и отбрасывает один из выбранных флажков, тогда все флажки под выборкой должны быть сняты и наоборот.Множественный выбор строки в JTable

ответ

13

Использование @ примера судов на воздушной подушке и @ советы camickr, тем ниже пример показывает соответствующий пользовательский интерфейс. Хотя он использует кнопки, SelectionAction также подходит для меню или всплывающего окна.

Check A Bunch

import java.awt.*; 
import java.awt.event.ActionEvent; 
import javax.swing.*; 
import javax.swing.DefaultListSelectionModel; 
import javax.swing.table.DefaultTableModel; 

/** @see http://stackoverflow.com/questions/4526779 */ 
public class CheckABunch extends JPanel { 

    private static final int CHECK_COL = 1; 
    private static final Object[][] DATA = { 
     {"One", Boolean.TRUE}, {"Two", Boolean.FALSE}, 
     {"Three", Boolean.TRUE}, {"Four", Boolean.FALSE}, 
     {"Five", Boolean.TRUE}, {"Six", Boolean.FALSE}, 
     {"Seven", Boolean.TRUE}, {"Eight", Boolean.FALSE}, 
     {"Nine", Boolean.TRUE}, {"Ten", Boolean.FALSE}}; 
    private static final String[] COLUMNS = {"Number", "CheckBox"}; 
    private DataModel dataModel = new DataModel(DATA, COLUMNS); 
    private JTable table = new JTable(dataModel); 
    private DefaultListSelectionModel selectionModel; 

    public CheckABunch() { 
     super(new BorderLayout()); 
     this.add(new JScrollPane(table)); 
     this.add(new ControlPanel(), BorderLayout.SOUTH); 
     table.setPreferredScrollableViewportSize(new Dimension(250, 175)); 
     selectionModel = (DefaultListSelectionModel) table.getSelectionModel(); 
    } 

    private class DataModel extends DefaultTableModel { 

     public DataModel(Object[][] data, Object[] columnNames) { 
      super(data, columnNames); 
     } 

     @Override 
     public Class<?> getColumnClass(int columnIndex) { 
      if (columnIndex == CHECK_COL) { 
       return getValueAt(0, CHECK_COL).getClass(); 
      } 
      return super.getColumnClass(columnIndex); 
     } 

     @Override 
     public boolean isCellEditable(int row, int column) { 
      return column == CHECK_COL; 
     } 
    } 

    private class ControlPanel extends JPanel { 

     public ControlPanel() { 
      this.add(new JLabel("Selection:")); 
      this.add(new JButton(new SelectionAction("Clear", false))); 
      this.add(new JButton(new SelectionAction("Check", true))); 
     } 
    } 

    private class SelectionAction extends AbstractAction { 

     boolean value; 

     public SelectionAction(String name, boolean value) { 
      super(name); 
      this.value = value; 
     } 

     @Override 
     public void actionPerformed(ActionEvent e) { 
      for (int i = 0; i < dataModel.getRowCount(); i++) { 
       if (selectionModel.isSelectedIndex(i)) { 
        dataModel.setValueAt(value, i, CHECK_COL); 
       } 
      } 
     } 
    } 

    private static void createAndShowUI() { 
     JFrame frame = new JFrame("CheckABunch"); 
     frame.add(new CheckABunch()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 
+0

См. Комментарии [здесь] (http://stackoverflow.com/a/14077632/230513), если [сортировка] (http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#sorting) включен. – trashgod

+0

Привет, я сожалею, что ответил, но я только что нашел это некоторое время назад и хотел бы внести свой вклад в добавление слушателя к изменениям в списке. Прямо сейчас я использую mouseListener, но он стреляет, прежде чем список будет фактически обновлен. Как я могу добавить слушателя, чтобы получать обновления для списка, когда они происходят? – Sam

+0

Возможно, «TableCellEditor», увиденный здесь (http://stackoverflow.com/a/7539298/230513)? – trashgod

2

Вы можете получить интервал выбора с кодом, аналогичным образом:

table.getSelectionModel().addListSelectionListener(new ListSelectionListener(){ 
    public void valueChanged(ListSelectionEvent e) { 
     minSelectedRow = ((DefaultListSelectionModel)e.getSource()).getMinSelectionIndex(); 
     maxSelectedRow = ((DefaultListSelectionModel)e.getSource()).getMaxSelectionIndex(); 
    } 
}); 

Затем, когда один флажок (слушать ItemEvent), вы должны повторять от minSelectedRow к maxSelectedRow и изменить установленные флажки состояние. Вот и все.

4

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

Затем вы можете использовать table.getSelectedRows(), чтобы получить индексы всех выбранных строк, которые необходимо обновить.

+0

ты прав .... когда-либо флажок щелкает все выбор строки теряется ..... есть ли способ обойти это без использования правой кнопки мыши ..? – sasidhar

+0

Вы не можете использовать мышь для двух разных функций. Это правильный пользовательский интерфейс. Я дал одно предложение использовать всплывающее меню. Другое решение - использовать menuItems из меню с ускорителями для выбора/отмены выбора. Таким образом, пользователь может использовать мышь или клавиатуру. Или вы можете добавить кнопки в пользовательский интерфейс, чтобы сделать то же самое. – camickr

+0

Я должен согласиться с @camickr; Я добавил пример рядом. – trashgod

2

Я согласен с Романом в том, что его идея будет работать, если вы используете поле класса, чтобы удерживать выбор min и max. Например:

import javax.swing.*; 
import javax.swing.event.ListSelectionEvent; 
import javax.swing.event.ListSelectionListener; 
import javax.swing.event.TableModelEvent; 
import javax.swing.event.TableModelListener; 
import javax.swing.table.DefaultTableModel; 

public class CheckABunch extends JPanel { 
    private static final Object[][] DATA = {{"One", Boolean.TRUE}, {"Two", Boolean.FALSE}, 
     {"Three", Boolean.TRUE}, {"Four", Boolean.FALSE}, {"Five", Boolean.TRUE}, 
     {"Six", Boolean.FALSE}, {"Seven", Boolean.TRUE}, {"Eight", Boolean.FALSE}}; 
    private static final String[] COLUMNS = {"Number", "CheckBox"}; 
    private DefaultTableModel model = new DefaultTableModel(DATA, COLUMNS) { 
     @Override 
     public Class<?> getColumnClass(int columnIndex) { 
      if (columnIndex == 1) { 
       return getValueAt(0, 1).getClass(); 
      } 
      return super.getColumnClass(columnIndex); 
     } 
    }; 
    private JTable table = new JTable(model); 
    private int minSelectedRow = -1; 
    private int maxSelectedRow = -1; 
    boolean tableModelListenerIsChanging = false; 

    public CheckABunch() { 
     add(new JScrollPane(table)); 

     table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { 
      public void valueChanged(ListSelectionEvent e) { 
       if (e.getValueIsAdjusting()) { 
        return; 
       } 
       minSelectedRow = ((DefaultListSelectionModel) e.getSource()).getMinSelectionIndex(); 
       maxSelectedRow = ((DefaultListSelectionModel) e.getSource()).getMaxSelectionIndex(); 
      } 
     }); 

     model.addTableModelListener(new TableModelListener() { 
      public void tableChanged(TableModelEvent e) { 
       if (tableModelListenerIsChanging) { 
        return; 
       }     
       int firstRow = e.getFirstRow(); 
       int column = e.getColumn(); 

       if (column != 1 || maxSelectedRow == -1 || minSelectedRow == -1) { 
        return; 
       } 
       tableModelListenerIsChanging = true; 
       boolean value = ((Boolean)model.getValueAt(firstRow, column)).booleanValue(); 
       for (int i = minSelectedRow; i <= maxSelectedRow; i++) { 
        model.setValueAt(Boolean.valueOf(value), i, column); 
       } 

       // *** edit: added two lines 
       minSelectedRow = -1; 
       maxSelectedRow = -1; 

       tableModelListenerIsChanging = false; 
      } 
     }); 
    } 

    private static void createAndShowUI() { 
     JFrame frame = new JFrame("CheckABunch"); 
     frame.getContentPane().add(new CheckABunch()); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowUI(); 
      } 
     }); 
    } 
} 
+0

@Hovercraft Full Of Eels, хотя ваш код имеет смысл, когда я выполнял свою систему, и он вел себя совершенно неожиданным образом, выбор сгустки работает просто отлично, но после этого обычный выбор также включает в себя подборку пучков ..... – sasidhar

+0

@Hovercraft Full Of Eels флажок 2, снимите флажок 2, а затем установите флажок 4 ..... затем автоматически проверяется коробка 2 ... – sasidhar

+0

Я не удивлен, так как это должно произойти, если 2 все еще выбранный, который я считал желаемым поведением для программы. Если вы установите или снимите флажок, все выбранные строки будут имитировать это состояние флажка, включая одну выбранную строку, оставшуюся от последнего выбора. Если вы не желаете этого поведения, один из способов - установить минимальную и максимальную выделенную строку на -1 в конце метода TableModelListener tableChanged. Я обновлю код ниже, чтобы показать, что я имею в виду. –

Смежные вопросы