JTable - Zellen auswahl deaktivieren und Fokus nicht anzeigen

DarthShader

Erfahrenes Mitglied
Hallo,

ist es möglich, ein JTable dazu zu bringen, dass ich keine Zelle, keine Zeile und keine Spalte auswählen/markieren kann? Ich möchte demnach auch nicht, dass ich den Inhalt einer Zelle bearbeiten möchte.

Und zusätzlich möchte ich noch nicht mal, dass der Fokus gemalt wird - klickt man auf eine Zelle in einer JTable, so wird ja um die Zelle herum so ein grauer Rand gezeigt, um anzuzeigen, wo der Fokus sitzt, auch das möchte ich nicht.

Ist es möglich, eine JTable so einzustellen?

Danke!
 
Hi Sascha,

danke für Deine Antwort. Das klappt so auch, allerdings habe ich vergessen zu erwähnen, dass man die einzelnen Zellen immer noch anklicken können muss.

Oder anders ausgedrückt, wenn ich auf eine Zelle klicke, dann möchte ich z.B. den Inhalt auf der Konsole ausgeben.

Ist die Tabelle aber disabled, so bekomme ich auch nix vom SelectionModel zurück. Kann man vielleicht mit anderen Listenern an einer anderen Stelle so ein Klick auf eine Zelle abfangen? Falls nicht, dann muss ich die Tabelle doch auf enabled setzen.
 
Vielleicht gibt es eine einfachere Lösung aber hier:

Code:
import java.awt.BorderLayout;
import java.awt.Component;
import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;

public class Tabletest extends JTable{

    public static void main(String[] args) {
        JFrame fr = new JFrame();
        DefaultTableModel dtm = new DefaultTableModel(){

            @Override
            public boolean isCellEditable(int row, int column) {
                return false;
            }        
        };
        
        final JTable tab = new JTable();
        dtm.setRowCount(25);
        dtm.setColumnCount(25);
        tab.setModel(dtm);
        tab.setDefaultRenderer(Object.class, new renderer());
        tab.getSelectionModel().addListSelectionListener(new ListSelectionListener(){
            @Override
            public void valueChanged(ListSelectionEvent e) {
                System.out.println("selected");
                System.out.println(tab.getSelectedColumn());
                System.out.println(tab.getSelectedRow());
            }
        });
        
        tab.setCellSelectionEnabled(false);
        fr.add(tab, BorderLayout.CENTER);

        fr.setSize(800, 600);
        fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        fr.setVisible(true);
    }
}

class renderer extends JLabel implements TableCellRenderer{

    public Component getTableCellRendererComponent(JTable table,
            Object value, boolean isSelected, boolean hasFocus, int row,
            int column) {
        if (value != null){
            this.setText(value.toString());
        }
        // TODO Auto-generated method stub
        return this;
    }
    
}
 
Hi Ryu20,

hm ja, das sieht ja gar nicht schlecht aus. Der Knackpunkt ist der "tab.setDefaultRenderer" - mit einem eigenen rendert man eben nicht den Fokus.

Wenn ich das Programm ausprobiere, bekomme ich aber immer nur mit (es gibt nur dann eine Ausgabe) wenn ich auf verschiedene Zeilen klicke. Klicke ich in derselben Zeile Zellen in verschiedenen Spalten an, gibt es keine Ausgabe.

(Klicke auf Zelle 0,0, dann auf 1,0, dann auf 2,0 etc... um es nachzuvollziehen).

Hast Du eine Idee, woran das liegen könnte?

Danke!
 
Das liegt daran, dass der ListSelectionListener nur reagiert, wenn eine neue Zeile markiert wurde.

Schau mal hier
Java:
import java.awt.BorderLayout;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JTable;

public class TableTest extends JTable{

    public static void main(String[] args) {
        JFrame fr = new JFrame();
        
        
        final JTable tab = new JTable(10,10);
        tab.setEnabled(false);
        tab.addMouseListener(new MouseAdapter(){

			

			@Override
			public void mousePressed(MouseEvent e) {
				System.out.println("Selected");
				System.out.println(tab.rowAtPoint(e.getPoint()));
				System.out.println(tab.columnAtPoint(e.getPoint()));
			}

			
        });
        
        fr.add(tab, BorderLayout.CENTER);

        fr.setSize(800, 600);
        fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        fr.setVisible(true);
    }
}

MFG

Sascha
 
bei meinem code musst du noch dem ColumnModel ein ListSelection Listener hinzufügen.

Code:
        this.getColumnModel().getSelectionModel().addListSelectionListener(....);

oder nimm die andere Lösung mit dem MouseListener :)
 
Das liegt daran, dass der ListSelectionListener nur reagiert, wenn eine neue Zeile markiert wurde.

Schau mal hier

Ah ok, noch ein neuer Ansatz - ich kannte die beiden Methoden
rowAtPoint und columnAtPoint nicht - dadurch kann man natürlich, wie
Du gezeigt hast, nen normalen MouseListener verwenden.



bei meinem code musst du noch dem ColumnModel ein ListSelection Listener hinzufügen.

Ah ok, dadurch merkt er dann auch Spalten-Auswahlen.


Nun, jetzt habe ich mehr als genug verschiedene Möglichkeiten, das so umzusetzen, vielen Dank an Euch beide!
 
Zuletzt bearbeitet von einem Moderator:
Sers!

Ich sitz vor nem ähnlichen Problem. Bei mir haks nur, weil durch den Code:

Code:
tab.getSelectionModel().addListSelectionListener(new ListSelectionListener().......
tab.getColumnModel().getSelectionModel().addListSelectionListener(....);

die Methode "valueChanged" doppelt aufgerufen wird, wenn sich die Selektion ändert. MouseListener ist leider keine Option für mich, da ich Selektierung per Tastatur einbeziehen muss.

Jemand eine Idee das zu verhindern?

Gruß macsx
 
Zurück