Checkbox in Jtable setzen

Alles zur oder um die NetBeans IDE

Moderator: arittner

Checkbox in Jtable setzen

Beitragvon Sunny » 22.07.2010, 16:43

Hallo,
folgendes Problem.
Ich lade in eine JTable Daten vom SQL-Server.
Das heißt das Tablemodel existiert schon uns soll nicht überschrieben werden.
Wie bekomme ich nachdem die Daten in der JTable schon vorhanden sind eine Checkbox ans Ende oder Anfang der Tabelle.

Mit diesem Code ist nur false oder true sichtbar und man sieht die Checkbox erst wenn man in die Zelle klickt.
TableColumn testColumn = jXTable.getColumnModel().getColumn(0);
DefaultCellEditor df = new DefaultCellEditor(new JCheckBox("Check"));
testColumn.setCellEditor(df);

Hoffe mir kann jemand helfen.
Gruß
Sunny
Benutzeravatar
Sunny
 
Beiträge: 64
Registriert: 02.11.2008, 01:12

Re: Checkbox in Jtable setzen

Beitragvon Olek77 » 22.07.2010, 16:57

Hi,

Du musst zuzüglich zu dem Editor noch einen TableCellRenderer installieren.
Schaue bei google nach Java+JTable+Tutorial.
Achte auch darauf, dass du bei der column wo du die Checkbox haben möchtest
boolean hast oder sie nachträglich zu booleans konvertierst. Sonst kann der
Editor nichts mit den dortigen Werten anfangen.

Gruß,

Olek
- Netbeans Certified Associate -
Benutzeravatar
Olek77
 
Beiträge: 130
Registriert: 21.03.2009, 15:09

Re: Checkbox in Jtable setzen

Beitragvon arittner » 23.07.2010, 18:50

Moin!

Ein sehr gutes Tutorial: http://download.oracle.com/docs/cd/E174 ... table.html

IMHO müsste für Boolean (das Objekt!) der passende Renderer schon existieren.

Beste Grüße,
Josch.
JNBB/BeanDev: Das deutsche Blog zur NetBeans Platform
Bild
Sun Certified Specialist for NetBeans IDE
Benutzeravatar
arittner
 
Beiträge: 2861
Registriert: 05.08.2008, 08:20
Wohnort: Südniedersachsen

Re: Checkbox in Jtable setzen

Beitragvon Olek77 » 23.07.2010, 18:51

Hi,

IMHO müsste für Boolean (das Objekt!) der passende Renderer schon existieren.


Das ist richtig. Für alle Primitiven Datentypen hat JTable schon den passenden Renderer.

Olek
- Netbeans Certified Associate -
Benutzeravatar
Olek77
 
Beiträge: 130
Registriert: 21.03.2009, 15:09

Re: Checkbox in Jtable setzen

Beitragvon Sunny » 23.07.2010, 22:55

Hallo zusammen,
vielen Dank für die Antworten.
Der Link war hilfreich.
Allerdings bekomme ich das mit dem TableCellRenderer nicht hin.

Olek, vielleicht kannst du mir einen Beispielcode senden bzw. den ergänzen.
Wäre super.

Tschüß
Sunny

//Table wird mit Daten gefüllt wobei die 3. Column einfach leer ist, weil ich da die Checkboxen einfügen möchte.
jXTable1.setModel(get.meinTableModel());

TableColumn testColumn = jXTable1.getColumnModel().getColumn(3);
JCheckBox cb = new JCheckBox("Test");
testColumn.setCellEditor(new DefaultCellEditor(cb));

TableCellRenderer tr = new TableCellRenderer() {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

if (isSelected) {
table.getSelectionForeground();
table.getSelectionBackground();
} else {
table.getForeground();
table.getBackground();
}
return table;
}} ;
tr.getTableCellRendererComponent(jXTable1,cb, true, true, 1, 3);
Benutzeravatar
Sunny
 
Beiträge: 64
Registriert: 02.11.2008, 01:12

Re: Checkbox in Jtable setzen

Beitragvon Olek77 » 25.07.2010, 19:37

Hallo,

Also das mit dem Renderer ist nicht ganz offensichtlich gemacht.
Man muss erstmal verstehen wie der überhaupt funktioniert.

Erstens ist es wichtig zu verstehen was zurückgeben werden soll bei der einen wichtigen Methode
Code: Alles auswählen
public Component getTableCellRendererComponent(JTable table,
                                               Object value,
                                               boolean isSelected,
                                               boolean hasFocus,
                                               int row,
                                               int column)


Wenn du einen DefaultTableCellRenderer benutzt ist der Rückgabewert nicht table, wie man vielleicht denken könnte,
sondern this.

Wieso 'this'? Das liegt daran, dass DefaultTableCellRenderer von einem speziellen JLabel erbt.
Dieses kümmert sich um den alle paint-Angelegenheiten, die in einer Tabellenzelle vorkommen sollen.

Also ist jede Tabellenzelle per default ein JLabel. Außer es handelt sich um den Spezialfall Boolean, dann
wird per default eine JCheckBox gesetzt.

Alles was du also in der Zelle tuen möchtest musst du mit dem JLabel machen. Also die Methoden
des JLabels nutzen. Wie z.B. setText, setBackground, setBorder etc.

Zweitens ist es eine merkwürdige Angelegenheit wenn man anfängt sich damit zu beschäftigen.
Denn man wird feststellen, dass wenn man einen eigenen Code in der obigen Methode schreibt,
den man für spezielle Fälle auslegt, auch die anderen Zellen in der gleichen Weise gezeichnet werden.

Das liegt daran, dass aus Performancegründen, immer nur eine Kopie der Zelle für dessen Fall du ein eigenes
Setting festgelegt hast gezeichnet wird. Also sagen wir du sagst für alle Zellen mit gerader Zeilenzahl möchte
ich einen blauen Hintergrund. Dann erscheinen alle Zeilen mit blauem Hintergrund.
Denn du hast den else Fall nicht angegeben.

Du müsstest also sagen
Code: Alles auswählen
if( row % 2 == 0 ){
   setBackground( Color.BLUE );
}
else{
   setBackground( Color.WHITE );
}


Die Methode ist somit kompliziert aber mächtig.
Du kannst für alle möglichen Fälle von vorkommen von Zellen zig Variationen von code schreiben.
Nur muss man aufpassen, dass auch die Fälle die man "nicht vor hat speziell zu behandeln" einen
default-case zugeordnet bekommen.

Im übrigen geht auch
Code: Alles auswählen
if( ... ) {
...
} else {
setBackrgound( getBackground() );
}

So definierst du für einen bestimmten Fall den Vordergrund und für alles andere benutzt du die Systemvorgabe.

In deinem Falle spielt das alles erst mal keine so große Rolle, da du ja "nur" die Checkbox zeichnen möchtest. ;)

Für den Fall bieten sich mind. zwei Möglichkeiten an.

1. Nehmen wir an du hast in einer column( sagen wir 2 ) Integer-Werte abgelegt, die entweder 1 oder 0 sind ( oder sonst wie binär ).
Dann reicht es wenn du schreibst:
Code: Alles auswählen
public Component getTableCellRendererComponent(JTable table,
                                               Object value,
                                               boolean isSelected,
                                               boolean hasFocus,
                                               int row,
                                               int column) {
   // würde ich immer zuerst prüfen um nicht ärgerliche NullPointer zu erhalten
   if( value != null ) {
      if( column == 2 && value instanceof Integer ) {
         Integer num = ( Integer ) value;
         // achtung hier wird es etwas tricky...
         Boolean trueOrFalse = num == 1 ? Boolean.TRUE : Boolean.FALSE;
         // wir erzeugen eine JCheckBox die wir zurückgeben
         JCheckBox cBox = new JCheckBox( "hier kannst du was schreiben", trueOrFalse );
         // jetzt geben wir einfach cBox zurück
         return cBox;
      // also alle anderen column's oder wenn der Wert in der 2. column nicht vom Typ Integer ist.
      } else {
         // wir lassen das JLabel die Zeichnung der Zelle übernehmen ( kommt darauf an was sich für ein Wert im Modell an der
         // Stelle befindet.
         return this;
      }
   // value war null also kein "sinnvoller" Wert - wir geben auch null zurück
   // Alternativ könnte man hier auch mit roter Schrift eine Warnung ausgeben.
   // dann müsste man setForeground, setText etc. und auch return this.
   } else {
      return null;
   }
}


Natürlich gibt es hierfür ein sehr schönes und ausführliches Tutorial
http://download.oracle.com/docs/cd/E174 ... table.html

Wenn man erst mal hinter den Mechanismus gestiegen ist, ist es eine sehr gute "Erfindung", die einem einen sehr
großen Spielraum zulässt.

Die zweite Variante wäre einen eigenen Renderer zu schreiben nur für die zweite column.
Wie du einen Renderer nur für eine column zuweist, weist du ja.

Dann würdest du aber nicht den DefaultTableCellRenderer benutzten sondern
eine eigene Klasse schreiben, die das Interface TableCellRenderer implementiert und von JCheckBox erbt.
Dann brauchst du nur wieder zu checken ob die Werte ( value ) ok sind und kannst dann
Code: Alles auswählen
setSelected( trueOrFalse );

in der obigen Methode aufrufen.

Richtig erfahrene gui-Programmierer erben auch einfach von JPanel oder noch allgemeiner von JComponent und definieren dann
komplexe Layouts, die jede Tabelle/Baum/Liste/(BaumTabelle) sehr professionell aussehen lassen.

Da das ganze aber recht aufwendig ist und man auch auf Performance achten muss ( je mehr gezeichnet werden muss, desto langsamer wird es )
sollte man als Anfänger sich nicht unbedingt daran wagen ( ich weis wovon ich spreche ;) - "Hä wieso wird jetzt Zelle x/y nicht so gezeichnet ??? :wink: " )

Hoffe dir hilft das weiter.

Gruß,

Olek
- Netbeans Certified Associate -
Benutzeravatar
Olek77
 
Beiträge: 130
Registriert: 21.03.2009, 15:09

Re: Checkbox in Jtable setzen

Beitragvon Olek77 » 25.07.2010, 19:42

PS:

Das nächste "Problem" ergibt sich wenn du die JCheckBox auch anklickbar machen möchtest und das auch funktionieren soll.
Das geht nur dann gut wenn du mit Boolean arbeitest und den default Renderer und default Editor setzt.
Wenn du mit z.B. Integer arbeitest geht das nicht mehr so trivial.

Gruß,

Olek
- Netbeans Certified Associate -
Benutzeravatar
Olek77
 
Beiträge: 130
Registriert: 21.03.2009, 15:09

Re: Checkbox in Jtable setzen

Beitragvon Sunny » 30.07.2010, 00:35

Hi Olek,
oh man da hast du dir ja echt viel Mühe gegeben.
Vielen vielen Dank dafür und ich denke du hilfst nicht nur mir sondern auch anderen die ähnliche
Fragen haben und hier ev. landen werden.

Gruß
Sunny
Benutzeravatar
Sunny
 
Beiträge: 64
Registriert: 02.11.2008, 01:12


Zurück zu NetBeans - IDE

Wer ist online?

Mitglieder in diesem Forum: Google [Bot], Yahoo [Bot] und 2 Gäste