Einzelne Zeile in jTable selektieren


#1

Moin zusammen,
ich habe in einer Anwendung div. Reiter mit jeweils eigenen Tables.
Dort werden u. a. weitere Anwendungen (Clients) und ihre Lizenzen verwaltet. Zu jeder Client-Tabelle gehört immer eine entsprechende Lizenz-Tabelle.

Während man nun in den Lizenz-Tabelle lustig per Mouseclick einzelne Zeilen markieren kann, klappt dies in den Client-Tabellen leider nicht. Dort bekomme ich rein gar nix markiert … :frowning:

Hier mal ein Code, bei dem es funktioniert

   private void createTableWorkerLiz()
   {
       m_DataReportWorkerLizenzen = new LicenseDBWorkerDataReport( this );
       m_TableWorkerLizenzen = new JTable();
       m_TableWorkerLizenzen.setAutoCreateColumnsFromModel( false );
       m_TableWorkerLizenzen.setModel( m_DataReportWorkerLizenzen );
       for( int spalte = 0; spalte < LicenseDBWorkerDataReport.m_columns.length; spalte++ )
       {
           TableCellRenderer renderer;
           switch( spalte )
           {
               case LicenseDBWorkerDataReport.COL_AKTIV:
               case LicenseDBWorkerDataReport.COL_FEATUREPUTONHOLD:
        // und weitere ...
               {
                   renderer = new CheckCellRenderer();
                   break;
               }

               case LicenseDBWorkerDataReport.COL_BTNEDIT:
               case LicenseDBWorkerDataReport.COL_BTNDELETE:
               {
                   renderer = new LicenseDBButtonRenderer();
                   break;
               }

               default:
               {
                   ColoredLicenseTableCellRenderer ctr = new ColoredLicenseTableCellRenderer();
                   ctr.setHorizontalAlignment( LicenseDBWorkerDataReport.m_columns[spalte].m_alignment );
                   renderer = ctr;
               }
           } // switch

           TableCellEditor editor = null;
           switch( spalte )
           {
               case LicenseDBWorkerDataReport.COL_AKTIV:
               {
                   JCheckBox cbActive = new JCheckBox();
                   cbActive.setHorizontalAlignment( JCheckBox.CENTER );
                   cbActive.setBackground( m_TableWorkerLizenzen.getBackground() );
                   editor = new DefaultCellEditor( cbActive );
                   ((DefaultCellEditor)editor).setClickCountToStart( 2 );
                   cbActive.addActionListener( new mainFrame_jCheckBoxWorkerLicenseActive_actionAdapter(this) );
                   break;
               }
        // weitere cases für alle Spalten
               case LicenseDBWorkerDataReport.COL_BTNEDIT:
               case LicenseDBWorkerDataReport.COL_BTNDELETE:
               {
                   editor = new LicenseDBButtonEditor( this, new JCheckBox(), "Push me!", "Ouch", LT_WORKER );
                   editor.addCellEditorListener( new LicenseDBCellListener(m_TableWorkerLizenzen,spalte,"Side A","Side B") );
                   break;
               }

               default:
                   editor = null;
           } // switch

           TableColumn column = new TableColumn( spalte, LicenseDBWorkerDataReport.m_columns[spalte].m_width, renderer, editor );
           column.setHeaderRenderer( createDefaultRenderer() );
           m_TableWorkerLizenzen.addColumn( column );
       } // for

       JTableHeader headerWorker = m_TableWorkerLizenzen.getTableHeader();
       headerWorker.setUpdateTableInRealTime( true );
       headerWorker.addMouseListener( new WorkerLizenzColumnListener() );
       headerWorker.setReorderingAllowed( true );
       spnWorkerLizenzen.getViewport().add( m_TableWorkerLizenzen );

       rowHeaderTableWorkerLizenzen = new JList<Object>( new TableListModel(m_TableWorkerLizenzen) );
       rowHeaderTableWorkerLizenzen.setFixedCellWidth( 30 );
       rowHeaderTableWorkerLizenzen.setBackground( spnWorkerLizenzen.getBackground() );
       rowHeaderTableWorkerLizenzen.setFixedCellHeight( m_TableWorkerLizenzen.getRowHeight() );
       rowHeaderTableWorkerLizenzen.setCellRenderer( new RowHeaderRenderer(m_TableWorkerLizenzen) );
       rowHeaderTableWorkerLizenzen.addMouseListener( new MouseAdapter()
       {
           public void mouseClicked( MouseEvent e )
           {
               int index = rowHeaderTableWorkerLizenzen.locationToIndex( e.getPoint() );
               m_TableWorkerLizenzen.setRowSelectionInterval( index, index );
               m_TableWorkerLizenzen.requestFocus();
           }
       });
       spnWorkerLizenzen.setRowHeaderView( rowHeaderTableWorkerLizenzen );
       rowHeaderTableWorkerLizenzen.repaint();
   } // createTableWorkerLiz
 

und die zugehörige Tabelle, in der nichts selektiert werden kann

     /**
        * @brief Erzeugt eine JTable für den Reiter <tt>Worker</tt> und fügt sie in das zugehörige Panel ein
        */
       private void createTableWorker()
       {
           m_DataReportWorker = new WorkerDataReport( this, LT_WORKER );
           m_TableWorker = new JTable();
           m_TableWorker.setAutoCreateColumnsFromModel( false );
           m_TableWorker.setModel( m_DataReportWorker );

        // #######################################################
        // ##### diese drei Zeilen habe ich neu eingefügt !! #####
           m_TableWorker.setSelectionMode( ListSelectionModel.SINGLE_INTERVAL_SELECTION );
           m_TableWorker.setColumnSelectionAllowed( false );
           m_TableWorker.setRowSelectionAllowed( true );
        // #######################################################

           for( int k = 0; k < WorkerDataReport.m_columns.length; k++ )
           {
               TableCellRenderer renderer;
               if( k == WorkerDataReport.COL_LICENSE_AKTIV )
               {
                   renderer = new CheckCellRenderer();
               }
               else
               {
                   ColoredWorkerTableCellRenderer ctr = new ColoredWorkerTableCellRenderer();
                   ctr.setHorizontalAlignment( WorkerDataReport.m_columns[k].m_alignment );
                   renderer = ctr;
               }

               TableCellEditor editor;
               if( k == WorkerDataReport.COL_LICENSE_AKTIV )
               {
                   JCheckBox cbActive = new JCheckBox();
                   cbActive.setHorizontalAlignment(JCheckBox.CENTER);
                   cbActive.setBackground(m_TableWorker.getBackground());
                   editor = new DefaultCellEditor(cbActive);
                   ((DefaultCellEditor)editor).setClickCountToStart( 2 );
                   cbActive.addActionListener( new mainFrame_jCheckBoxWorkerIsLicenseActive_actionAdapter(this) );
               }
               else
               {
                   editor = new DefaultCellEditor(new JTextField());
               }
               TableColumn column = new TableColumn( k, WorkerDataReport.m_columns[k].m_width, renderer, editor );
               column.setHeaderRenderer( createDefaultRenderer() );
               m_TableWorker.addColumn( column );
           }

           JTableHeader headerWorker = m_TableWorker.getTableHeader();
           headerWorker.setUpdateTableInRealTime( true );
           headerWorker.addMouseListener( new WorkerColumnListener() );
           headerWorker.setReorderingAllowed( true );
           spnWorkerData.getViewport().add( m_TableWorker );

           rowHeaderTableWorker = new JList<Object>( new TableListModel(m_TableWorker) );
           rowHeaderTableWorker.setFixedCellWidth( 30 );
           rowHeaderTableWorker.setBackground( spnWorkerData.getBackground() );
           rowHeaderTableWorker.setFixedCellHeight( m_TableWorker.getRowHeight() );
           rowHeaderTableWorker.setCellRenderer( new RowHeaderRenderer(m_TableWorker) );
           rowHeaderTableWorker.addMouseListener( new MouseAdapter()
           {
               public void mouseClicked( MouseEvent e )
               {
                   int index = rowHeaderTableWorker.locationToIndex( e.getPoint() );
                   m_TableWorker.setRowSelectionInterval( index, index );
                   m_TableWorker.requestFocus();
               }
           });

           spnWorkerData.setRowHeaderView( rowHeaderTableWorker );
           rowHeaderTableWorker.repaint();
       } // createTableWorker

die drei Zeilen mit “setSelectionMode” etc. habe ich mir Web angelesen, bringen aber nichts. Wobei sie ja im ersten Beispiel, WO ich selektieren kann, auch nicht drin sind …
Uns so wie ich es verstanden habe, muss ich doch “RowSelectionAllowed” auf TRUE und “ColumnSelectionAllowed” auf FALSE setzen, damit klar ist, dass Zeilen und keine Spalten selektiert werden sollen, oder ??
Aber auch andere Wertekombinationen bringen nichts!

Ich habe auch mit “setCellSelectionEnabled” rumgespielt, aber auch ohne jeglichen Erfolg!
Auch kann ich einzelne Zellen editierbar machen, aber selektiert wird weiterhin nicht!

Habe auch versucht, nach einem Tipp in einem anderen Forum, einen “cellSelectionModel.addListSelectionListener” zu bauen. Hiermit wurde mir zwar ggf. der Inhalt einer selektierten Zelle angezeigt, aber von Selektion keine Spur …

Habe mir auch mal die Renderer angeschaut, aber auch die machen hier nix Aufregendes!

An den Stellen, wo die Table deklariert und einem ScrollPanel zu gewiesen werden, sehe ich weiter auch nichts !

Bin inzwischen reichlich ratlos … :rage:
Hat irgendwer eine Idee, wonach ich noch suchen könnte ???

Hier noch ein Beispiel, was mit ‘markieren/selektieren’ gemeint ist:
WorkerLiz

Danke und VG
Klaus

BTW: kann ich hier Code-Tags nur noch händisch einfügen ???


#2

Viel code mit viel anwendungsspezifischem, was man nur schwer nachvollziehen kann - das in irgendwas compilierbares zu verwandeln ist nicht möglich …?


#3

Moin,

ja, ich weiß :thinking:

“Leider” funktioniert kurzer Beispielcode, so wie man ihn im Web findet rsp. mir in einem anderen Forum gepostet wurde, relativ problemlos, würde also nicht viel bringen.
Baue ich das bei mir ein, klappt es nur eben leider nicht!
Da beide von mir geposteten Code ja relativ gleich sind, habe ich eigentlich das dumpfe Gefühl, dass es nicht daran liegt … es fühlt sich so an, als ob die Tabellen einzelner Reiter oder eben einzelne Reiter quasi nicht anklickbar sind (wobei ich ein bestimmtes Feld in dieser Table (mit einer CheckBox) bei Bedarf sogar editieren kann (da wird dann über einen globalen Button ein Bearbeitungsstatus hierfür freigegeben). Aber auch das wirkt sich in keiner Weise auf das selektieren aus :tired_face:

Auch die Stellen, wo diese Create-Funktionen aufgerufen werden rsp. die Tables den jeweiligen Scrollpanels zuwiesen werden, sind absolut unauffällig. Ich habe mir da schon “einen Wolf” gedebuggt …

VG Klaus


#4

Wie äussert sich das nicht selektiert sein in deinem code

Ist dies nur, dass visuell nichts markiert ist? - Dann solltest du dir die verwendeten CellRenderer ansehen ob diese auch
korrekt auf
Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)

isSelected und hasFocus reagieren.

oder bekommst du auch bei table.getSelectedRows(); nichts zurück?

LG Amunra


#5

Moin,
Danke für Deine Antwort!

genau!
In der Lizenztabelle wird die ganze Zeile blau und die Zelle, auf die man klickt bekommt eine blauen Rahmen, so als ob sie editbar wäre (was sie allerdings nicht ist!!).
Im anderen Fall passiert einfach gar nichts, so als ob das Ganze irgendwie geschützt ist … :sob:

Die Renderer sind eigentlich in beiden Fällen sie gleichen …
Die “getTableCellRendererComponent”-Methoden sind vlt. ein guter Hinweis, die werde ich mal näher untersuchen! :thinking:

Das “getSelectedRows” verwende ich scheinbar gar nicht …
Dumm gefragt, wo müsste ich das denn aufrufen??

VG Klaus


#6

Zum debuggen könntest du dir einen MouseListener auf die Table machen und immer bei mouse clicked abfragen welche Zeilen selektiert sind (und einfach Sysout.println oder eine Logausgabe wenn du einen Logger hast machen). Wenn da nie etwas zurück kommt, scheint wirklich etwas mit dem selektieren nicht zu funktionieren,

LG


#7

Moinsen,
so, es schaut so aus, als ob ich das Problem gefunden habe :stuck_out_tongue_winking_eye:
Es gab noch einen weiteren CellRender, der von mir (bedingt durch eine sehr unglückliche Namensgebung seitens meines Vorgängers) stumpf übersehen worden war :weary:
Hier fehlte ggf. das spezifische Setzen des “SelectionFore-” und “Backgrounds” …

setBackground( (isSelected && !hasFocus) ? table.getSelectionBackground() : table.getBackground() );
setForeground( (isSelected && !hasFocus) ? table.getSelectionForeground() : table.getForeground() );
setBorder( hasFocus ? m_focusBorder : m_noFocusBorder );
setBorder( hasFocus ? UIManager.getBorder("Table.focusCellHighlightBorder") : m_noFocusBorder );

Ich muss das zwar jetzt in unserem Testsystem noch intensiv für alle Gegebenheiten durchtesten, aber es schaut gut aus :upside_down_face:

Danke, dass Du mich auf die richtige Fährte ‘gelockt’ hast :relaxed:

VG Klaus


#8

Schön wenn ich helfen konnte.

Arbeite selber an einer alten Swing-Anwendung und hab schon viel mit den JTables gespielt.
(Schon mal versucht eine editierbare Tabelle zu haben, die mehrzeiligen Code mit HTML markup erlaubt :slight_smile: )


#9

Moin,

nee nee, ich bin ja nicht größenwahnsinnig :grin:
Habe hier mit dieser Anwendung, die ich den letzten Wochen und Monaten übernommen habe, schon genug zu tun :relaxed:

VG Klaus


#10

Das hat man oft, wenn man nicht als erste Zeile im Renderer

super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

aufruft. Wenn du nicht explizit andere Farben für den Vordergrund/Hintergrund setzen willst, kannst du dir dann auch diese Zeilen dafür sparen.


#11

Moin,

Leider ist die Tabelle auf Wunsch unseres Chefs recht bunt :rofl:
Einzelne Spalten werden bei verschiedenen Systemzuständen in verschiedenen Farben markiert. Deswegen auch dieser spezifische Renderer, den ich übersah …

VG Klaus