Domanda

Voglio essere in grado di avere un JPanel in una cella con un JButton che fa un certo lavoro quando si fa clic.

Ho cercato HOWTO circa Editori cella, ma tutti gli esempi parlare di sostituire la cella con un altro componente (per esempio sostituire un int con un JTextField ecc) La mia situazione è un po 'diversa:

Ho la seguente ADT

class MyClass {
  public String title;
  public String url;
  public String path;
  public int annotations;
}

Ho creato un modello di cella di una tabella personalizzata che ha 1 colonna e la classe per quella colonna è MyClass. Poi ho creato un renderer di celle per quella classe che restituisce un JPanel come illustrato di seguito:

MyClass cellulare renderer

Come si può vedere, il JPanel contiene un pulsante. Voglio che questo pulsante per lanciare un JFrame ogni volta cliccato. Tutte le idee?

Se si intende suggerire cellulare Editor, si prega di essere un po 'più specifico su come farlo. Se possibile, fornire qualche pseudo-codice.

Grazie.

P.S. Sono abbastanza sicuro che il titolo di questa interrogazione ha bisogno di qualche lavoro. ;)

È stato utile?

Soluzione

Dopo aver di coding.mof risposta , ho finalmente fatto quello che volevo. Tuttavia, ho voluto una risposta più completa per questa domanda, in modo da fornirò uno io.

Quindi, renderer di celle è sufficiente disegnare il componente e non consentono alcuna interazione all'interno di esso. Mentre Editors cellulari fanno.

Inizialmente, tutte le celle della JTable sono componenti che vengono restituiti dal renderer registrato. Tuttavia, quando si seleziona una cella, questa componente viene sostituito da un componente che viene restituito dal curatore. Questi due possono effettivamente essere diversi componenti! Quali Sono abbastanza sicuro che si può trarre vantaggio da questo e fare alcune cellule funky: P

In ogni caso, in questo esempio, sia il renderer e il display editore dello stesso componente, quindi dovremo creare un componente che verrà utilizzato da entrambi.

In primo luogo, abbiamo bisogno di creare un TableModel che restituisce la nostra ADT:

class MyClassTableModel extends DefaultTableModel {
  List<MyClass> data;

  public MyClassTableModel(List<MyClass> data) {
    this.data = data;
  }

  public Class<?> getColumnClass(int columnIndex) { return MyClass.class; }
  public int getColumnCount() { return 1; }
  public String getColumnName(int columnIndex) { return "MyClass"; }
  public int getRowCount() { return (data == null) ? 0 : data.size(); }
  public Object getValueAt(int rowIndex, int columnIndex) { return data.get(rowIndex); }
  public boolean isCellEditable(int rowIndex, int columnIndex) { return true; }
}

Ora, creiamo un componente che verrà condiviso tra il rendering e l'Editor:

class MyClassCellComponent extends JPanel() {
  MyClass myClass;

  public MyClassCellComponent() {
    // initialize components (labels, buttons, etc.)
    // add action listeners
  }

  public void updateData(MyClass myClass, boolean isSelected, JTable table) {
    this.myClass = myClass;
    // update buttons, labels etc. accordingly
  }
}

i parametri della tabella isSelected e sono utilizzati per rendere lo sfondo del pannello e sono opzionali. Ecco come il renderer utilizza il nostro componente:

class MyClassCellRenderer implements TableCellRenderer {
  MyClassCellComponent panel;

  public MyClassCellRenderer() {
    panel = new MyClassCellComponent();
  }

  public Component getTableCellRendererComponent(JTable table, Object value,        boolean isSelected, boolean hasFocus, int row, int column) {
    MyClass myClass = (MyClass)value;
    panel.updateData(myClass, isSelected, table);
    return panel;
  }
}

E qui è come l'editor lo utilizza:

class MyClassCellEditor extends AbstractCellEditor {
  MyClassCellComponent panel;
  public MyClassCellEditor() {
    panel = new MyClassCellComponent();
  }
  public Component getTableCellEditorComponent(JTable table, Object value,      boolean isSelected, int row, int column) {
    MyClass myClass = (MyClass)value;
    panel.updateData(myClass, true, table);
    return panel;
  }
  public Object getCellEditorValue() {
    return null;
  }
}

Questo è tutto. Ora possiamo semplicemente creare un JTable come segue:

JTable myClassTable = new JTable(new MyClassTableModel());
myClassTable.setDefaultRenderer(MyClass.class, new MyClassCellRenderer());
myClassTable.setDefaultEditor(MyClass.class, new MyClassCellEditor());

E abbiamo finito!

P.S. Sono abbastanza sicuro che possiamo combinare il rendering e l'Editor in una singola classe si estende AbstractCellEditor e attrezzi TableCellRenderer, ma io non sono sicuro di prestazioni.

Altri suggerimenti

public class MyTableCellEditor extends AbstractCellEditor implements TableCellEditor { 

JComponent pan = new JPanel();

public MyTableCellEditor () {
  pan.add(btn);
  // add all elments you need to your panel
  btn.addActionListener( /* the listener which will handle the events */ );
}

public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int rowIndex, int vColIndex) { 
   btn.setText( /* according to row or whatever*/ );
   // set all elemnts of you panel to the according values
   // or add dynamically an action listener
   return pan;
}
public Object getCellEditorValue() { return new Void(); } 
} 

Quindi nel tuo ascoltatore si dovrà verificare la selezione del tavolo in modo da poter rispondere in modo diverso per ogni riga. Se si desidera mantenere tutti gli elementi in una colonna è possibile sostituire il JButton con il pannello contenente tutti i componenti. Il JTable sarà poi inoltrare tutti gli eventi di quel JPanel.

Si potrebbe creare una tabella con più colonne, quindi è possibile aggiungere una colonna separata per contenere il pulsante. Il Tabella classe Button Colonna ti permette di fare questo con facilità .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top