Swing Einzelne Zelle in JTable soll NICHT auswählbar sein

Status
Nicht offen für weitere Antworten.

boesi

Aktives Mitglied
moin

Ich habe eine JTable mit so ner Art Zwischenüberschriften. Wenn der Nutzer auf diese Zellen bzw Zeilen klickt, soll einfach nichts, also gar nichts passieren.

Ich kann zwar DnD und editieren verhindern, aber ...

Das Problem: sobald diese "Überschrift" angeklickt wird, wird die gerade aktive Zelle deselektiert, bzw der TableCellEditor geschlossen. Wie läßt sich das verhindern?

Ich hab an der JTable einen MouseListener hängen - dort kann ich in den Methoden mousePressed, mouseClicked und mouseReleased zwar die Methode consume aufrufen - das funktioniert aber nicht. Und ListSelectionEvent bietet consume nicht.

cu boesi
 

Ebenius

Top Contributor
Die einzige saubere Möglichkeit ist eine eigene Implementation des [c]ListSelectionModel[/c]-Interfaces. Also am besten von DefaultListSelectionModel ableiten und alle Methoden überschreiben die irgendwie die Selektion setzen oder erweitern.

Hinweis: Nicht vergessen, dass die Zeilenangaben im [c]ListSelectionModel[/c] aus View-Perspektive gesehen werden, das heißt, man muss sie über JTable.convertRowIndexToModel(int) konvertieren, um auf Zeilen im Modell schließen zu können. Ansonsten verbaut man sich den Weg der Sortierung / des Filterns per RowSorter.

Happy Hacking!
Ebenius
 

boesi

Aktives Mitglied
Die einzige saubere Möglichkeit ist eine eigene Implementation des [c]ListSelectionModel[/c]-Interfaces. Also am besten von DefaultListSelectionModel ableiten und alle Methoden überschreiben die irgendwie die Selektion setzen oder erweitern.
Da ich nur SINGLE_SELECTION nutze, sollte das nicht weiter schwer sein - dachte ich mir...

Hab jetzt also folgende Klasse erstellt:
Java:
public class JobSelectionModel extends DefaultListSelectionModel {
	JTable table;
	public JobSelectionModel(JTable table) {
		super();
		this.table = table;
	}
	@Override
	public void setSelectionInterval(int index0, int index1) {
		int row = this.table.convertRowIndexToModel(index1);
		JobTableModel model = (JobTableModel) this.table.getModel();
		if (model.getRowType(row) != JobType.HEADER)
			super.setSelectionInterval(index0, index1);
	}
}
und binde die dann so ein:
Java:
myTable.setSelectionModel(new JobSelectionModel(myTable));

Tja was bringt's? Die Überschriften können immer noch selektiert werden, dafür funktioniert mein TransferHandler nicht mehr *grummel* ???:L
 

Ebenius

Top Contributor
Du musst noch ein bisschen mehr als nur [c]setSelectionInterval()[/c] überschreiben. Da gibt's noch add und insert und setLead und so...

Ebenius
 

boesi

Aktives Mitglied
Hab die Klasse jetzt ein bisschen angepasst:
Java:
public class JobSelectionModel extends DefaultListSelectionModel {
	
	JTable table;
	int rowOld = -1;

	public JobSelectionModel(JTable table) {
		super();
		this.table = table;
	}
	
	@Override
	public void setSelectionInterval(int index0, int index1) {
		int rowNew = this.table.convertRowIndexToModel(index1);
		JobTableModel model = (JobTableModel) this.table.getModel();
		if (model.getRowType(rowNew) == JobType.HEADER) {
			final int col = this.table.getSelectedColumn();
			if (col != -1 && this.rowOld != -1) {
				SwingUtilities.invokeLater(new Thread()  {
					@Override
					public void run() {
						JobSelectionModel.this.table.editCellAt(JobSelectionModel.this.rowOld, col);
					}
				});
			}
		} else {
			this.rowOld = rowNew;
			super.setSelectionInterval(index0, index1);
		}
	}
}
Aber das ist jetzt echt hackish.

Der Angriff bei setSelectionInterval ist wohl etwas spät ... und das Problem mit DnD löst sich damit auch nicht
 

boesi

Aktives Mitglied
Du musst noch ein bisschen mehr als nur [c]setSelectionInterval()[/c] überschreiben. Da gibt's noch add und insert und setLead und so...
Hoppla eben war dein Post bei mir noch nicht zu sehen ...
Ich setz dann mal ein paar Breakpoints und schau welche der Funktionen konkret aufgerufen werden
 

Ebenius

Top Contributor
Nicht, dass mir das Verhalten so gefallen würde... Aber bei mir funktioniert das wirklich gut:
Java:
/* (@)JTableSelectionFun.java */

/* Copyright 2009 Sebastian Haufe

 * Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       [url]http://www.apache.org/licenses/LICENSE-2.0[/url]

 * Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License. */

package com.ebenius;

import java.awt.*;

import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;

public class JTableSelectionFun {

  private interface LockedRowManager {

    boolean isLocked(int row);
  }

  /**
   * Test main method.
   * 
   * @param args ignored
   */
  public static void main(String[] args) {
    final LockedRowManager lockManager = new LockedRowManager() {

      public boolean isLocked(int row) {
        return (row % 3) == 2;
      }
    };

    final JTable table = new JTable(100, 3);
    table.setSelectionModel(new DefaultListSelectionModel() {

      @Override
      public void addSelectionInterval(int index0, int index1) {
        if (!checkRangeLocked(lockManager, index0, index1)) {
          super.addSelectionInterval(index0, index1);
        }
      }

      @Override
      public void setSelectionInterval(int index0, int index1) {
        if (!checkRangeLocked(lockManager, index0, index1)) {
          super.setSelectionInterval(index0, index1);
        }
      }

      private boolean checkRangeLocked(
            final LockedRowManager lockManager,
            int index0,
            int index1) {
        boolean locked = false;
        int low = Math.min(index0, index1);
        final int high = Math.max(index0, index1);
        if (low > -1 && high > -1) {
          for (int i = low; i <= high && !locked; i++) {
            if (lockManager.isLocked(i)) {
              locked = true;
            }
          }
        }
        return locked;
      }
    });
    table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() {

      @Override
      public Component getTableCellRendererComponent(
            JTable table,
            Object value,
            boolean isSelected,
            boolean hasFocus,
            int row,
            int column) {
        super.getTableCellRendererComponent(table, value, isSelected,
              hasFocus, row, column);
        setEnabled(!lockManager.isLocked(row));
        return this;
      }

      @Override
      protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (!isEnabled()) {
          final Insets ins = getInsets();
          final int mid = (getHeight() + ins.top - ins.bottom) / 2;
          g.setColor(Color.RED);
          g.drawLine(ins.left, mid, getWidth() - ins.right, mid);
          g.drawLine(ins.left, mid + 1, getWidth() - ins.right, mid + 1);
        }
      }
    });
    final JPanel contentPane = new JPanel(new BorderLayout(6, 6));
    contentPane.add(new JScrollPane(table));

    final JFrame f = new JFrame("Test Frame: JTableSelection"); //$NON-NLS-1$
    f.setContentPane(contentPane);
    f.pack();
    f.setLocationRelativeTo(null);
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.setVisible(true);
  }
}
Was das Problem mit DnD ist, weiß ich nicht.

Ebenius
 

boesi

Aktives Mitglied
Nicht, dass mir das Verhalten so gefallen würde... Aber bei mir funktioniert das wirklich gut:
Vielen Dank für das Beispiel, das verdeutlicht mein Problem sehr gut. Wenn eine nicht-auswählbare Zelle angeklickt wird, wird der CellEditor geschlossen - und genau das will ich verhindern. Wenn in meiner Anwendung eine Zeile ausgewählt wird, wird automatisch der CellEditor geöffnet (bei den "Überschriften" natürlich nicht) - eigentlich will ich eine Liste und keine Tabelle, aber die JList kennt keinen Editor.
Was das Problem mit DnD ist, weiß ich nicht.
Ich glaube das liegt an meinem restlichen Programm-Code - der ist etwas komplizierter, weil sich durch meinen CellEditor die Zeilenhöhen verändern ...
 

Ebenius

Top Contributor
Vielen Dank für das Beispiel, das verdeutlicht mein Problem sehr gut. Wenn eine nicht-auswählbare Zelle angeklickt wird, wird der CellEditor geschlossen - und genau das will ich verhindern. Wenn in meiner Anwendung eine Zeile ausgewählt wird, wird automatisch der CellEditor geöffnet (bei den "Überschriften" natürlich nicht) - eigentlich will ich eine Liste und keine Tabelle, aber die JList kennt keinen Editor.
Okay. Und schon wird aus der Pflicht die Kür. :-D

Mit einem eigenen CellEditor und etwas Voodoo kann man das verhindern. Passend zu meinem Beispiel oben:
[java=78]
table.setDefaultEditor(Object.class, new DefaultCellEditor(
new JTextField()) {

@Override
public boolean stopCellEditing() {
final AWTEvent event = EventQueue.getCurrentEvent();
final JTable table =
(JTable) SwingUtilities.getAncestorOfClass(JTable.class,
getComponent());
if (event instanceof MouseEvent && event.getSource() == table) {
final int row = table.rowAtPoint(((MouseEvent) event).getPoint());
if (lockManager.isLocked(row)) {
return false;
}
}
return super.stopCellEditing();
}
});
[/code]
Ebenius
 

boesi

Aktives Mitglied
Okay. Und schon wird aus der Pflicht die Kür. :-D

Mit einem eigenen CellEditor und etwas Voodoo kann man das verhindern. Passend zu meinem Beispiel oben:
Hey du hast das Problem gelöst :applaus: Vielen Dank dafür. Aber der Gedanke "Eine neue Zeile kann nicht ausgewählt werden, wenn der Editor nicht geschlossen wird" ist schon irgendwie von hinten durch die Brust ins Auge. Aber das Ergebniss ist am Ende doch schön simpel - ein eigenes ListSelectionModel brauchts in meinem Fall auch nicht.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
HoT Einzelne Zelle in JTable Rahmen unten setzen AWT, Swing, JavaFX & SWT 24
T einzelne Zelle einer JTable auswählen und Hintergrundfarbe ändern AWT, Swing, JavaFX & SWT 2
J JTable: Einzelne Zelle selektieren AWT, Swing, JavaFX & SWT 6
S JavaFX TableView einzelne Zelle Layout zuweisen AWT, Swing, JavaFX & SWT 3
A Mit JavaFX einzelne Zeilen in TableView farbig markieren AWT, Swing, JavaFX & SWT 5
P AWT Einzelne Komponenten zur Laufzeit austauschen? AWT, Swing, JavaFX & SWT 3
J JavaFX TabPane / Wie füge ich einzelne items ? AWT, Swing, JavaFX & SWT 1
VfL_Freak Swing Einzelne Zeile in jTable selektieren klappt nicht AWT, Swing, JavaFX & SWT 7
T AWT Grafik"Array" einzelne Elemente verschieben AWT, Swing, JavaFX & SWT 1
S Swing JTable - Einzelne Rows einfärben AWT, Swing, JavaFX & SWT 11
L Swing CellRenderer für einzelne Zellen? AWT, Swing, JavaFX & SWT 5
N jFreeChart einzelne Punkte anwählen und Formatieren AWT, Swing, JavaFX & SWT 0
M JavaFX TextArea einzelne Buchstaben färben AWT, Swing, JavaFX & SWT 3
T Swing Einzelne Teile eines Textes färben? AWT, Swing, JavaFX & SWT 10
M Einzelne Ordner im JFileChooser ausgrauen? AWT, Swing, JavaFX & SWT 4
D Swing Mit TableCellRenderer einzelne Zellen markieren AWT, Swing, JavaFX & SWT 3
R einzelne Zeichen in jTable einlesen AWT, Swing, JavaFX & SWT 10
M Swing Einzelne Fenster schließen AWT, Swing, JavaFX & SWT 2
V JTable: Zugriff auf einzelne Zellen AWT, Swing, JavaFX & SWT 4
K Swing CellEditor für einzelne Zellen AWT, Swing, JavaFX & SWT 2
K Swing JTable Editierfunktion für einzelne Zellen ausschalten AWT, Swing, JavaFX & SWT 3
S Einzelne JComboBox in JTable austauschen AWT, Swing, JavaFX & SWT 4
F Einzelne TreeNode an einem JTree editierbar machen AWT, Swing, JavaFX & SWT 3
C JTree Einzelne Objekte färben AWT, Swing, JavaFX & SWT 4
C Spielfeld Gitter - Einzelne Zellen verändern AWT, Swing, JavaFX & SWT 18
J CellRenderer einzelne zellen Hintergrund AWT, Swing, JavaFX & SWT 9
M JTable einzelne Zeilen färben AWT, Swing, JavaFX & SWT 2
A Swing JTree Editable einzelne Nodes editierbar machen! AWT, Swing, JavaFX & SWT 2
T JTable - Einzelne Spalte nicht sortieren? AWT, Swing, JavaFX & SWT 2
R JTable einzelne Zellen selektieren AWT, Swing, JavaFX & SWT 7
H Einzelne Pixel auf Transparenz überprüfen? AWT, Swing, JavaFX & SWT 3
X Einzelne Border setzen AWT, Swing, JavaFX & SWT 2
F png-Datei erstellen und einzelne Pixel schreiben AWT, Swing, JavaFX & SWT 2
J MVC- einzelne Sichten auf einer Hauptsicht anzeigen AWT, Swing, JavaFX & SWT 3
S Einzelne Frame Fenster schließen AWT, Swing, JavaFX & SWT 2
S Einzelne Frame Fenster schließen AWT, Swing, JavaFX & SWT 2
P JTextArea - einzelne Zeile löschen bzw einfügn AWT, Swing, JavaFX & SWT 2
G Einzelne Objekte neu zeichnen AWT, Swing, JavaFX & SWT 8
B einzelne Zellen scrollbar machen innerhalb einer Tabelle AWT, Swing, JavaFX & SWT 3
E JTable einzelne reihe editierbar machen AWT, Swing, JavaFX & SWT 2
I einzelne Zellen bei JTable markieren AWT, Swing, JavaFX & SWT 3
C JTable: Einzelne Spalten nicht editierbar machen AWT, Swing, JavaFX & SWT 2
W Kleine Sub-Tabelle in SpreadsheetView-Zelle anzeigen AWT, Swing, JavaFX & SWT 9
S TableCellRender - Zelle auf editier-/anklickbar setzen AWT, Swing, JavaFX & SWT 5
F Best-Practise: JTable Text in Zelle zu groß AWT, Swing, JavaFX & SWT 2
missy72 JavaFX TableView / TableColumn / ObservableList / zwei Werte in einer Zelle AWT, Swing, JavaFX & SWT 2
P JavaFX aktuelle Tabellenzeile bei Choice-Box-Auswahl in Zelle ermitteln AWT, Swing, JavaFX & SWT 28
T Zelle- und die Zeile-Farbenwechsel bei der Selektion in der Tabelle AWT, Swing, JavaFX & SWT 4
P JavaFX TableView Zelle markieren AWT, Swing, JavaFX & SWT 3
W Swing JTable Zeilenumbruch innerhalb einer Zelle AWT, Swing, JavaFX & SWT 3
M Swing Automatischer Editorstart in JTable-Zelle AWT, Swing, JavaFX & SWT 5
M Wert einer Zelle aus JTable ziehen AWT, Swing, JavaFX & SWT 4
P Fokus auf Zelle in JTable AWT, Swing, JavaFX & SWT 1
LexeB4F Zelle in JTable gezielt einfärben AWT, Swing, JavaFX & SWT 4
LexeB4F JTable mehrere Zelle selektieren und inhalte Löschen.. Ideen gesucht AWT, Swing, JavaFX & SWT 1
K Swing JTable mit ImageIcon und Text in einer Zelle AWT, Swing, JavaFX & SWT 1
E JavaFX TableView mit Rechtsklick Zelle auswählen AWT, Swing, JavaFX & SWT 8
E JTable Hintergrund von geklickter Zelle ändern AWT, Swing, JavaFX & SWT 2
J CellFactory in Abhängigkeit von anderer Zelle AWT, Swing, JavaFX & SWT 4
M JTable: Prüfen ob Zelle leer ist AWT, Swing, JavaFX & SWT 5
O Swing JTable - Zelle fokussieren AWT, Swing, JavaFX & SWT 10
L JTable selektierte Zelle in Bearbeitungs Modus AWT, Swing, JavaFX & SWT 2
H Combobox in einer einzelnen Zelle der Jtable AWT, Swing, JavaFX & SWT 2
R Swing Hintergrundfarbe der Zelle in einer JTable bei Markierung AWT, Swing, JavaFX & SWT 2
M Jtable Objecte aus Zelle AWT, Swing, JavaFX & SWT 13
M Beim Start von TableEditor Inhalt der Zelle markieren. AWT, Swing, JavaFX & SWT 2
S Swing Zelle einer JTable hervorheben (ohne CellRenderer) AWT, Swing, JavaFX & SWT 3
A JTable Zelle markieren von bis und Löschen AWT, Swing, JavaFX & SWT 6
F JTable soll mit Buttons befüllt werden, aber nicht in jede Zelle einer Spalte AWT, Swing, JavaFX & SWT 3
T DefaultTableCellRenderer Farbe bestimmter Zelle ändern AWT, Swing, JavaFX & SWT 2
GianaSisters Swing ComboBox im jTable (in bestimmter Zelle nicht über die ganze Spalte) AWT, Swing, JavaFX & SWT 4
O JButton in Zelle von JTable AWT, Swing, JavaFX & SWT 4
K Tabellen Inhalt ( Zelle ) Modifizieren AWT, Swing, JavaFX & SWT 2
J Zelle eine JTable ändern AWT, Swing, JavaFX & SWT 3
R Drag an Drop JTable Zelle AWT, Swing, JavaFX & SWT 6
T JTable, Popup Fester per Rechtsklick auf Zelle AWT, Swing, JavaFX & SWT 19
H variable Höhe einer JTextArea (als Renderer/Editor) als Zelle einer JTable AWT, Swing, JavaFX & SWT 9
C Swing JTable zeigt in jeder Zelle einer Reihe denselben Inhalt AWT, Swing, JavaFX & SWT 2
lenniii Zelle in JTable ändern AWT, Swing, JavaFX & SWT 2
J Swing JTable, jede Zelle ein anderer Title im TitledBorder AWT, Swing, JavaFX & SWT 5
D JTables, Test highlighten innerhalb einer Zelle AWT, Swing, JavaFX & SWT 5
S Swing JTable nach einer Änderung einer Zelle komplett aktualisieren. AWT, Swing, JavaFX & SWT 10
N Methode zum ermitteln der editierte Zeile/Zelle in jTable AWT, Swing, JavaFX & SWT 8
C Swing JTable Zelle mit Einfachklick editieren AWT, Swing, JavaFX & SWT 3
C JTable: Mehrere Farben in einer Zelle darstellen AWT, Swing, JavaFX & SWT 10
D Swing Farbige Zelle ohne DefaultTableCellRenderer AWT, Swing, JavaFX & SWT 17
D Swing Farbige Zelle ohne DefaultTableCellRenderer AWT, Swing, JavaFX & SWT 4
T Swing JTable - true zurückbekommen, wenn der Cursor in einer Zelle blinkt AWT, Swing, JavaFX & SWT 7
C JTable markierte Zelle wird bei removeRow nicht mit gelöscht AWT, Swing, JavaFX & SWT 6
Dit_ Verschiedene Icons in einer JTable-Zelle AWT, Swing, JavaFX & SWT 2
A JTable Zelle Padding AWT, Swing, JavaFX & SWT 9
R JTable Hintergrund der Zeile abhängig von Inhalt einer Zelle verändern AWT, Swing, JavaFX & SWT 3
S Swing DnD: Wie finde ich heraus, von welcher Zelle aus im JTable der Drag gestartet wurde? AWT, Swing, JavaFX & SWT 3
U LayoutManager [GBL] Component aus einer Zelle löschen AWT, Swing, JavaFX & SWT 2
E Zelle in JTable nach klick markieren AWT, Swing, JavaFX & SWT 2
O JTable Zelle mit "ENTER" in Editmode setzen AWT, Swing, JavaFX & SWT 4
eskimo328 JTable nächste Zelle nach Eingabe einer Ziffer AWT, Swing, JavaFX & SWT 5
A Swing JTable Icon nur in einer Zelle AWT, Swing, JavaFX & SWT 2
B Swing JTable merkt sich die zuletzt selektierte Zelle AWT, Swing, JavaFX & SWT 3
M JTable - verlassen einer Zelle AWT, Swing, JavaFX & SWT 15

Ähnliche Java Themen

Neue Themen


Oben