JTable - Spaltenzellen nicht fokusierbar machen

Status
Nicht offen für weitere Antworten.

jherz

Mitglied
Hallo,

ich habe eine JTable mit Selektionskonfiguration
setRowSelectionAllowed(true);
setColumnSelectionAllowed(false);
In dieser Tabelle möchte ich verhindern dass Zellen in Spalten 1 und 2 den Fokus bekommen können. Also die gepunktete Linie weder per Mausklick noch per Tastaturbedienung erhalten können.

Irgendeine Idee wie sich das erreichen lässt? Ich hänge da seit drei Tagen dran und komme nicht dahin.

Grüße,
Jürgen
 

Ebenius

Top Contributor
Ich dachte eigentlich schon, ich bekomme das ganze überhaupt nicht mehr hin. Das Hauptproblem besteht in der Navigation die natürlich in Actions gemacht wird die vom TableUI installiert werden. Alle Navigations-Aktionen (und das sind etliche) gehen davon aus, dass jede Zelle selektiert werden kann. Man müsste alle ersetzen um eine Einhundertprozentlösung zu erreichen... :(

Außerdem habe ich den Ansatz getestet, einfach zwei Tabellen nebeneinander auf ein JPanel-Derivat zu legen, dieses auf dem Viewport eines JScrollPane zu installieren und alle Gemeinsamkeiten gleich zu setzen; also gleiche TableModel-Instanz, gleiche RowSorter-Instanz, etc. Dann könnte man der linken Tabelle ein ColumnModel geben das nur die nicht auswählbaren Spalten kennt und der rechten eines das die auswählbaren Spalten kennt. Funktioniert auch problemlos. Allerdings benötigt man dann ein drittes Column Model, das beide Column Models hintereinander hängt, bei moveColumn aufpasst, dass es die Columns aus dem ersten nicht ins zweite verschieben kann, usw. Dann muss man noch circa 250 Zeilen Quelltext aus der JTable-Klasse kopieren (configureEnclosingScrollPane() und unconfiger...) damit die JScrollPane auch so aussieht wie die einer Tabelle und von dem Panel einen JTableHeader bekommt. Und dann muss dieses JPanel-Derivat auch noch Scrollable implementieren. Das wär's dann auch schon. :oops:

Nach einigen Tests und Gedankenspielen ist es dann wieder der Ansatz geworden den ich zuerst gehabt und fast verworfen hatte. Eine ColumnSelectionModel-Implementation die den LeadSelectionIndex prüft und verändert und eine ColumnModel-Implementation die das ColumnSelectionModel bzgl. der gesperrten Spalten aktualisieren kann. Ohne die Navigations-Aktionen anzufassen ist diese Lösung ebenfalls nicht einhundertprozentig. Wenn man bspw. die letzte Spalte sperrt, und mit TAB navigiert, dann gelangt man nicht in die nächste Zeile; das kann das ColumnSelectionModel ja auch nicht. Das SelectionModel rät eben nur, wohin es nun den LeadSelectionIndex verschieben soll, wenn der eigentlich gewünschte LeadIndex eine gesperrte Spalte trifft. Aber das Verhalten ist mindestens annehmbar. :)

Die Klassennamen gefallen mir nicht sonderlich, die Nested Classes und Interfaces sollten aus der Testklasse raus, die Methodennamen sind auch nicht ganz in Ordnung und Javadoc ist auch zu spärlich gesäht... Aber für den Anfang ist's okay. Teste mal, ob die Lösung zu Deinem Problem passt und ob Du sie so oder ähnlich übernehmen willst.
[HIGHLIGHT="Java"]import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.beans.PropertyChangeEvent;
import java.util.*;

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

public class TableCellFocusTest {

/**
* Extension of the {@link DefaultTableColumnModel} to support denying focus
* on specified columns. Note that the extension does not work if the
* selection model is re-assigned an instance not implementing the
* {@link ControlledLeadSelectionModel} interface.
*
* @version $Revision$ as of $Date$
* @author Sebastian Haufe
*/
static class FocusSelectableColumnModel extends DefaultTableColumnModel {

// -----------------------------------------------------------------------
// Instance fields
// -----------------------------------------------------------------------

private final Set<Object> notFocusable =
Collections.newSetFromMap(new WeakHashMap<Object, Boolean>());

// -----------------------------------------------------------------------
// Construction
// -----------------------------------------------------------------------

@Override
protected ListSelectionModel createSelectionModel() {
return new DefaultControlledLeadSelectionModel();
}

// -----------------------------------------------------------------------
// Overridden Methods
// -----------------------------------------------------------------------

@Override
public void moveColumn(int columnIndex, int newIndex) {
super.moveColumn(columnIndex, newIndex);
updateFocusableColumn(newIndex);
}

@Override
public void addColumn(TableColumn column) {
super.addColumn(column);
updateFocusableColumn(getColumnIndex(column.getIdentifier()));
}

@Override
public void removeColumn(TableColumn column) {
super.removeColumn(column);
}

@Override
public void propertyChange(PropertyChangeEvent evt) {
super.propertyChange(evt);
if ("identifier".equals(evt.getPropertyName())
&& notFocusable.remove(evt.getOldValue())) {
notFocusable.add(evt.getNewValue());
updateFocusableColumns();
}
}

private void updateFocusableColumns() {
final ListSelectionModel lsm = getSelectionModel();
if (lsm instanceof ControlledLeadSelectionModel) {
final ControlledLeadSelectionModel selModel =
(ControlledLeadSelectionModel) lsm;
final int columnCount = getColumnCount();
for (int i = 0; i < columnCount; i++) {
final TableColumn column = getColumn(i);
final Object identifier = column.getIdentifier();
selModel
.setAcceptedLeadIndex(i, !notFocusable.contains(identifier));
selModel.setSize(getColumnCount());
}
}
}

private void updateFocusableColumn(int index) {
final ListSelectionModel lsm = getSelectionModel();
if (lsm instanceof ControlledLeadSelectionModel) {
final ControlledLeadSelectionModel selModel =
(ControlledLeadSelectionModel) lsm;
final TableColumn column = getColumn(index);
final Object identifier = column.getIdentifier();
selModel.setAcceptedLeadIndex(index, !notFocusable
.contains(identifier));
selModel.setSize(getColumnCount());
}
}

// -----------------------------------------------------------------------
// API extension
// -----------------------------------------------------------------------

/**
* Set the given column focusable / unfocusable. If the column currently
* has focus, removes the focus.
*
* @param column the column
* @param focusable {@code true} to allow focus, {@code false} to deny
*/
public void setColumnFocusable(TableColumn column, boolean focusable) {
final Object identifier = column.getIdentifier();
final boolean changed;
if (focusable) {
changed = notFocusable.remove(identifier);
} else {
changed = notFocusable.add(identifier);
}

if (changed) {
updateFocusableColumn(getColumnIndex(identifier));
}
}

/**
* Determines for the given column whether it is focusable.
*
* @param column the column
* @return {@code true} if allowed to be focused, {@code false} if denied
*/
public boolean isColumnFocusable(TableColumn column) {
return !notFocusable.contains(column.getIdentifier());
}
}

/**
* Selection Model extension to support blocking certain indices for lead
* selection.
*
* @version $Revision$ as of $Date$
* @author Sebastian Haufe
*/
interface ControlledLeadSelectionModel extends ListSelectionModel {

/**
* Returns whether the given index is accepted as lead selection index
* within {@code this} selection model.
*
* @param index the index to check
* @return {@code true} if accepted
*/
boolean isAcceptedLeadIndex(int index);

/**
* Sets whether the given index is accepted as lead selection index within
* {@code this} selection model.
*
* @param index the index
* @param accepted
*/
void setAcceptedLeadIndex(int index, boolean accepted);

/**
* Sets the size of the selection model. The size is necessary to
* automatically determine an alternative lead index, if the original lead
* index is not accepted by {@link #isAcceptedLeadIndex(int)}.
*
* @param size the size
*/
void setSize(int size);

/**
* Gets the size of the selection model.
*
* @return the size
* @see #setSize(int)
*/
int getSize();
}

/**
* Default implementation of the {@link ControlledLeadSelectionModel}
* interface; automatically changing the lead index to an alternative index,
* if the desired lead index is not accepted.
* <p>
* Note that the algorithm to determine the alternative lead index is a
* trying to figure out the desired behavior from the, seen from the point
* of view of a user navigating with the cursor keys.
*
* @version $Revision$ as of $Date$
* @author Sebastian Haufe
*/
static class DefaultControlledLeadSelectionModel
extends DefaultListSelectionModel implements ControlledLeadSelectionModel {

private final BitSet leadBlocked = new BitSet();
private int size = 0;

// -----------------------------------------------------------------------
// Implementing LeadSelectableSelectionModel
// -----------------------------------------------------------------------

public boolean isAcceptedLeadIndex(int index) {
return !leadBlocked.get(index);
}

public void setAcceptedLeadIndex(int index, boolean accepted) {
leadBlocked.set(index, !accepted);
if (getLeadSelectionIndex() == index && !accepted) {
setLeadSelectionIndex(getLeadSelectionIndex());
}
}

public void setSize(int size) {
this.size = size;
}

public int getSize() {
return size;
}

// -----------------------------------------------------------------------
// Fix Index according to lead selectable rules
// -----------------------------------------------------------------------

private int findAcceptableLeadIndex(int index) {
if (index == -1) {
return -1;
}
final int oldLead = getLeadSelectionIndex();
final int dLead = index - oldLead;
final int maxIndex = getSize() - 1;

int result;
switch (dLead) {
// trivial, occurs on usual cursor navigation
case 1:
result = findForward(index, maxIndex);
if (result == -1) {
result = findForward(0, index);
}
break;
case -1:
result = findBackward(index, 0);
if (result == -1) {
result = findBackward(maxIndex, index);
}
break;
default:
if (oldLead == -1 || dLead >= 0) {
result = findForward(index, maxIndex);
if (result == -1) {
result = findBackward(index, 0);
}
} else {
result = findBackward(index, 0);
if (result == -1) {
result = findForward(index, maxIndex);
}
}
break;
}

return result != -1 || oldLead == -1
? result
: isAcceptedLeadIndex(oldLead) ? oldLead : -1;
}

private int findForward(int index, final int maxIndex) {
for (int i = index; i <= maxIndex; i++) {
if (isAcceptedLeadIndex(i)) {
return i;
}
}

return -1;
}

private int findBackward(int index, int minIndex) {
for (int i = index; i >= minIndex; i--) {
if (isAcceptedLeadIndex(i)) {
return i;
}
}

return -1;
}

// -----------------------------------------------------------------------
// Overridden Methods
// -----------------------------------------------------------------------

@Override
public void setLeadSelectionIndex(int index) {
super.setLeadSelectionIndex(findAcceptableLeadIndex(index));
}

@Override
public void moveLeadSelectionIndex(int leadIndex) {
super.moveLeadSelectionIndex(findAcceptableLeadIndex(leadIndex));
}

@Override
public void removeSelectionInterval(int index0, int index1) {
super.removeSelectionInterval(index0, findAcceptableLeadIndex(index1));
}

@Override
public void addSelectionInterval(int index0, int index1) {
super.addSelectionInterval(index0, findAcceptableLeadIndex(index1));
}

@Override
public void setSelectionInterval(int index0, int index1) {
super.setSelectionInterval(index0, findAcceptableLeadIndex(index1));
}

@Override
public void removeIndexInterval(int index0, int index1) {
final int gap = index1 - index0 + 1;
final int last = getSize() - gap;
for (int i = index1; i <= last; i++) {
leadBlocked.set(i, leadBlocked.get(i + gap));
}
size -= gap;

super.removeIndexInterval(index0, index1);
}

@Override
public void insertIndexInterval(int index, int length, boolean before) {
final int insMinIndex = (before) ? index : index + 1;
final int maxIndex = getSize() - 1;
for (int i = maxIndex; i >= insMinIndex; i--) {
leadBlocked.set(i + length, leadBlocked.get(i));
}
size += length;

super.insertIndexInterval(index, length, before);
}
}

// -------------------------------------------------------------------------
// Program Entry Point
// -------------------------------------------------------------------------

/**
* Test main method.
*
* @param args ignored
*/
public static void main(String[] args) {
final JTable table1 = new JTable(20, 10);
table1.setAutoCreateRowSorter(true);

final FocusSelectableColumnModel columnModel =
new FocusSelectableColumnModel();
table1.setColumnModel(columnModel);
table1.createDefaultColumnsFromModel();

final DefaultTableCellRenderer renderer = 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);
setBackground(Color.LIGHT_GRAY);
return this;
}
};

int[] blocked = { 0, 2, 8, 9 };
for (int i : blocked) {
final TableColumn col = columnModel.getColumn(i);
columnModel.setColumnFocusable(col, false);
col.setCellRenderer(renderer);
}

final JPanel mainPanel = new JPanel(new BorderLayout(6, 6));
mainPanel.add(new JScrollPane(table1), BorderLayout.CENTER);

final JFrame f = new JFrame("Table Cell Focus Fun");
f.setContentPane(mainPanel);
f.pack();
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
f.setVisible(true);
}
}[/HIGHLIGHT]
Gute Nacht.
Ebenius
 
Zuletzt bearbeitet:

jherz

Mitglied
Ich dachte eigentlich schon, ich bekomme das ganze überhaupt nicht mehr hin.
Wow, da scheinst Du Dich ja wirklich mächtig reingehängt zu haben. Und das nur auf meine knapp spezifizierte Anfrage hin. Da muß ich sagen Hut ab und herzlichen Dank.

Das Hauptproblem besteht in der Navigation die natürlich in Actions gemacht wird die vom TableUI installiert werden. Alle Navigations-Aktionen (und das sind etliche) gehen davon aus, dass jede Zelle selektiert werden kann. Man müsste alle ersetzen um eine Einhundertprozentlösung zu erreichen... :(
Ich habe schon befürchtet dass es da keine zentrale

Außerdem habe ich den Ansatz getestet, einfach zwei Tabellen nebeneinander auf ein JPanel-Derivat zu legen [...] Das wär's dann auch schon. :oops:[/QUOTE]
Ach so, also nicht der Rede wert. Mannomann, mir ist schon beim Lesen schwindlig geworden. ;)

Nach einigen Tests und Gedankenspielen ist es dann wieder der Ansatz geworden den ich zuerst gehabt und fast verworfen hatte. Eine ColumnSelectionModel-Implementation die den LeadSelectionIndex prüft und verändert und eine ColumnModel-Implementation die das ColumnSelectionModel bzgl. der gesperrten Spalten aktualisieren kann. Ohne die Navigations-Aktionen anzufassen ist diese Lösung ebenfalls nicht einhundertprozentig.
Ich habe in meinem Test jetzt keine Navigation gefunden die nicht funktioniert. Dabei kommen zwei wichtige Einschränkungen zum Tragen die ich in meiner Frage nicht erwähnt hatte weil ich Deinen Einsatz unterschätzt hatte.
1. Tab/Shift-Tab habe ich sowieso umkonfiguriert so dass es aus der Tabelle springt.
2. Mit Spalte 0 gibt es sowieso nur eine Spalte die überhaupt selektierbar sein soll, also fiele findAcceptableLeadIndex() in meinem Fall sowieso sehr simpel aus.

Aber auch als Allgemeinlösung gefällt mir Deine Arbeit.

Übrigens apropos Navigation, laut BasicTableUI gibt es eine Action mit dem Key "clearSelection" der JTable.clearSelection() aufruft. Ich bin bisher noch nicht draufgekommen wie ich zu einem bekannten actionMapKey einen KeyStroke ermitteln kann. Geht das? Und unabhängig davon, weißt Du welcher Shortcut clearSelection in einer Tabelle ausführt?

Jürgen
 

Ebenius

Top Contributor
Aber auch als Allgemeinlösung gefällt mir Deine Arbeit.
Man sieht an meinem Code hoffentlich wenigstens in Ansätzen, dass er darauf vorbereitet ist, im Bedarfsfall mit geringem Aufwand zur allgemeinen Lösung zu mutieren. :)

[...] weißt Du welcher Shortcut clearSelection in einer Tabelle ausführt?
Hängt vom TableUI ab. Im Metal L&F (BasicTableUI) ist diese Aktion nicht per KeyBinding verfügbar. In meinen Tabellen hab ich die Aktion aber im Kontextmenü.

Ich bin bisher noch nicht draufgekommen wie ich zu einem bekannten actionMapKey einen KeyStroke ermitteln kann. Geht das?
Natürlich, wenn auch nicht so performant und einfach wie andersherum (was ja der Standard-Anwendungsfall ist). Habe eben meine Utilities erweitert; schenk ich Dir. :D [HIGHLIGHT="Java"]/**
* Get the key strokes bound to the given action key from the given input
* map. The parent input maps' bindings are not included.
*
* @param im the input map to investigate
* @param actionKey the action key bound
* @return the array of keys, not {@code null}
* @throws NullPointerException if the input map or the action key is
* {@code null}
*/
public static KeyStroke[] boundKeys(InputMap im, Object actionKey) {
return boundKeys(im, actionKey, false);
}

/**
* Convenience method getting one of the given component's input maps. Get
* the key strokes bound to the given action key from that input map. The
* parent input maps' bindings are not included.
*
* @param component the component to get the input map from
* @param condition the kind of input map to get
* @param actionKey the action key bound
* @return the array of keys, not {@code null}
* @throws NullPointerException if the component or the action key is
* {@code null}
* @see JComponent#getInputMap(int)
*/
public static KeyStroke[] boundKeys(
JComponent component,
int condition,
Object actionKey) {
return boundKeys(component.getInputMap(condition), actionKey, false);
}

/**
* Get the key strokes bound to the given action key from the given input
* map. The parent input maps' bindings are included.
*
* @param im the input map to investigate
* @param actionKey the action key bound
* @return the array of keys, not {@code null}
* @throws NullPointerException if the input map or the action key is
* {@code null}
*/
public static KeyStroke[] allBoundKeys(InputMap im, Object actionKey) {
return boundKeys(im, actionKey, true);
}

/**
* Convenience method getting one of the given component's input maps. Get
* the key strokes bound to the given action key from that input map. The
* parent input maps' bindings are included.
*
* @param component the component to get the input map from
* @param condition the kind of input map to get
* @param actionKey the action key bound
* @return the array of keys, not {@code null}
* @throws NullPointerException if the component or the action key is
* {@code null}
* @see JComponent#getInputMap(int)
*/
public static KeyStroke[] allBoundKeys(
JComponent component,
int condition,
Object actionKey) {
return boundKeys(component.getInputMap(condition), actionKey, true);
}

/**
* Get the key strokes from the given input map, bound to the given action
* key.
*
* @param im the input map to investigate
* @param actionKey the action key bound
* @param includeParents whether or not to include all input map's parents
* @return the array of keys, not {@code null}
* @throws NullPointerException if the input map or the action key is
* {@code null}
*/
private static KeyStroke[] boundKeys(
InputMap im,
Object actionKey,
boolean includeParents) {

/* special handling for first match, as many actions are mapped to one
key stroke only */
KeyStroke firstMatch = null;
Collection<KeyStroke> matches = null;
do {
final KeyStroke[] keys = im.keys();
if (keys == null) {
continue;
}
for (final KeyStroke keyStroke : keys) {
final Object ak = im.get(keyStroke);
if (actionKey == ak || actionKey != null && actionKey.equals(ak)) {
if (firstMatch == null) {
firstMatch = keyStroke;
} else if (matches == null) {
matches = new HashSet<KeyStroke>(7);
matches.add(firstMatch);
matches.add(keyStroke);
} else {
matches.add(keyStroke);
}
}
}
} while (includeParents && (im = im.getParent()) != null);

return firstMatch == null ? new KeyStroke[0] : matches == null
? new KeyStroke[] { firstMatch }
: matches.toArray(new KeyStroke[matches.size()]);
}[/HIGHLIGHT]
Ebenius
 

André Uhres

Top Contributor
In dieser Tabelle möchte ich verhindern dass Zellen in Spalten 1 und 2 den Fokus bekommen können. Also die gepunktete Linie weder per Mausklick noch per Tastaturbedienung erhalten können.
Java:
table = new JTable() {
    private Border TRANSPARENT_BORDER = new LineBorder(new Color(0, 0, 0, 0));
    @Override
    public Component prepareRenderer(
            final TableCellRenderer renderer, final int row, final int column) {
        Component c = super.prepareRenderer(renderer, row, column);
        if (column < 2) {
            ((JComponent) c).setBorder(TRANSPARENT_BORDER);
        }
        return c;
    }
};
 

Ebenius

Top Contributor
André, damit bekommst Du aber ein Problem, wenn Du in der Tabelle navigierst. Du kannst in die "blinden" Zellen navigieren, hast kein Feedback mehr über den Fokus. Das ist kurz gesagt pfuiba. :)

[size=-2]... ganz davon abgesehen, dass es nicht in jedem L&F sinnvoll aussehen wird ...[/size]

Ebenius
 

Ebenius

Top Contributor
Ich weiss, aber im Originalpost ist Navigation kein Thema, nur die Darstellung. Allerdings ist es gewöhnlich umgekehrt.
Damit hast Du zwar Recht... Das Problem ist aber, dass die Anforderung des Entwicklers nicht viel mit den Erwartungen des Benutzers an ein GUI zu tun haben. Ich baue gute GUIs, da ist mir die ausdrückliche Anforderung des Entwicklers eher egal. ;)

BTW: Den Rand mit 0,0,0,0 zu initialisieren sieht zumindest mit Metal-L&F komisch aus. Da sollte der Rand 1,1,1,1 haben. Mit Nimbus brauchst Du auf der LINE_START-Seite (also links bei LTR, rechts bei RTL) mehr als ein Pixel; 2 oder 3, weiß nicht genau. Geschickter wäre es also, die Insets der vom Original-Renderer erzeugten Renderer-Komponente zu nehmen und damit einen EmptyBorder zu initialisieren.

Ebenius
 

André Uhres

Top Contributor
Damit hast Du zwar Recht... Das Problem ist aber, dass die Anforderung des Entwicklers nicht viel mit den Erwartungen des Benutzers an ein GUI zu tun haben. Ich baue gute GUIs, da ist mir die ausdrückliche Anforderung des Entwicklers eher egal. ;)

BTW: Den Rand mit 0,0,0,0 zu initialisieren sieht zumindest mit Metal-L&F komisch aus. Da sollte der Rand 1,1,1,1 haben. Mit Nimbus brauchst Du auf der LINE_START-Seite (also links bei LTR, rechts bei RTL) mehr als ein Pixel; 2 oder 3, weiß nicht genau. Geschickter wäre es also, die Insets der vom Original-Renderer erzeugten Renderer-Komponente zu nehmen und damit einen EmptyBorder zu initialisieren.

Ebenius
Grundsätzlich stimme ich dir zu. Man könnte aber auch sagen: Das Problem ist aber, dass die Anforderung des Benutzers nicht viel mit den Erwartungen des Entwicklers an ein GUI zu tun haben.
Beim Rand habe ich nicht die Grösse visiert, sondern die Farbe.
 

Ebenius

Top Contributor
Grundsätzlich stimme ich dir zu. Man könnte aber auch sagen: Das Problem ist aber, dass die Anforderung des Benutzers nicht viel mit den Erwartungen des Entwicklers an ein GUI zu tun haben.
Ein einfaches "Du hast Recht" hätte genügt. ;)

Beim Rand habe ich nicht die Grösse visiert, sondern die Farbe.
Stimmt, hab ich zu flüchtig hingesehen. In dem Fall stimmt's für Metal-L&F, für Nimbus aber nicht.

Ebenius
 

Ebenius

Top Contributor
Daß Nimbus keine Transparenz unterstützt, scheint mir wieder so ein Kuriosum zu sein.
Ne, das hast Du falsch verstanden. Nimbus hat im Standard-TableCellRenderer einfach links mehr Platz als ein Pixel. Deswegen passt die 1-Pixel-Breite des LineBorders nicht. Alpha-Kanal funktioniert genauso wie bei Metal.

Ebenius
 
Zuletzt bearbeitet:

André Uhres

Top Contributor
Ne, das hast Du falsch verstanden. Nimbus hat im Standard-TableCellRenderer einfach links mehr Platz als ein Pixel. Deswegen passt die 1-Pixel-Breite des LineBorders nicht. Alpha-Kanal funktioniert genauso wie bei Metal.
Ach so, naja ich halte eh nicht so viel von all den exotischen Lafs. Sie machen meist mehr Probleme als sie nützen.
 

Ebenius

Top Contributor
Ach so, naja ich halte eh nicht so viel von all den exotischen Lafs. Sie machen meist mehr Probleme als sie nützen.
Der Trick ist, von Anfang an an die Exoten zu denken. Ein Mac-Java hat von haus aus nix anderes als das entsprechende Mac-L&F. Wenn man von vornherein seine Apps gegen die üblichen Verdächtigen testet, dann geht's mit den anderen um so wahrscheinlicher auch klar.

Ebenius
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
I Swing JTable zeichnet kein vertical Grid AWT, Swing, JavaFX & SWT 6
J Drag und drop aus einer JTable - bitte um Unterstützung AWT, Swing, JavaFX & SWT 2
S HPRO und UPRO gemeinsame JTABLE gemeinsamer RENDERER ? AWT, Swing, JavaFX & SWT 1
F Swing JTable - MultiHeader inkl. Eingabemöglichkeit AWT, Swing, JavaFX & SWT 1
S JTable - Feldinhalte anzeigen AWT, Swing, JavaFX & SWT 15
D Swing JTable Spaltenbreite AWT, Swing, JavaFX & SWT 1
W Gibt es einen "automatischen Listener" in Swing oder JTable oder der ATM-Klasse? AWT, Swing, JavaFX & SWT 14
G jTable - getSelectedRow() AWT, Swing, JavaFX & SWT 3
I JTable mit einem Button zu einer Detail Seite springen AWT, Swing, JavaFX & SWT 4
P JTable Listener für die Änderung einzelner Zellen oder Rows AWT, Swing, JavaFX & SWT 2
D Tastaturabfragen CTRL+t, CTRL+E bei eine JTable, bestehend aus JTextAteas AWT, Swing, JavaFX & SWT 4
P Checkboxes in JTable nicht editable AWT, Swing, JavaFX & SWT 9
F Best-Practise: JTable Text in Zelle zu groß AWT, Swing, JavaFX & SWT 2
izoards JTable in CSV File schreiben... AWT, Swing, JavaFX & SWT 23
Kohl Jedes Objekt einer JTable um ein Zeichen verkürzen AWT, Swing, JavaFX & SWT 7
I JTable, DefaultTableModel, zwei Zahlen multiplizieren. AWT, Swing, JavaFX & SWT 26
M JTABLE / wie oft wurde gewürfelt. AWT, Swing, JavaFX & SWT 1
F JTable vergrößern AWT, Swing, JavaFX & SWT 2
H JTable: Diverse NullPointer-Exceptions zur Laufzeit AWT, Swing, JavaFX & SWT 3
J Swing Werte des JTable werden nicht angezeigt AWT, Swing, JavaFX & SWT 9
T Swing JTable cellRenderer mit jpg Hintergrundfarbe lässt sich nicht ändern. AWT, Swing, JavaFX & SWT 1
HoT Einzelne Zelle in JTable Rahmen unten setzen AWT, Swing, JavaFX & SWT 24
B JTable Zellen zusammenfügen AWT, Swing, JavaFX & SWT 3
M Swing Cell Renderer für Zeilenumbruch in JTable AWT, Swing, JavaFX & SWT 0
H JTable im JSplitPane darstellen AWT, Swing, JavaFX & SWT 2
MadMax2506 Swing JTable lädt sehr lange AWT, Swing, JavaFX & SWT 1
D Zeilenumbruch in einer JTable AWT, Swing, JavaFX & SWT 9
R Swing JTable und Spaltenausrichtung AWT, Swing, JavaFX & SWT 8
G JTable füllen AWT, Swing, JavaFX & SWT 1
H JTable TableCellEditor-Problem AWT, Swing, JavaFX & SWT 0
W Swing JTable Zeilenumbruch innerhalb einer Zelle AWT, Swing, JavaFX & SWT 3
J Datensatz in jTable ausgeben AWT, Swing, JavaFX & SWT 3
M Swing Automatischer Editorstart in JTable-Zelle AWT, Swing, JavaFX & SWT 5
ralfb1105 Swing JTable aktualisieren AWT, Swing, JavaFX & SWT 5
adiko01 JTable: Nur markierte Zeilen aus der Tabelle in CSV exportiern AWT, Swing, JavaFX & SWT 9
M JTable.setDefaultRenderer(...) greift nicht AWT, Swing, JavaFX & SWT 0
J JTable: Eingabe in Tabellenzelle korrigieren AWT, Swing, JavaFX & SWT 4
T Problem mit JTable Sortierung AWT, Swing, JavaFX & SWT 2
D JTable nach INSERT aktualisieren /refreshen AWT, Swing, JavaFX & SWT 1
D MySQL Daten in JTable anzeigen AWT, Swing, JavaFX & SWT 2
H Swing Jtable extra spalte AWT, Swing, JavaFX & SWT 6
S Swing Rechteck über JTable zeichnen (per MouseListener) AWT, Swing, JavaFX & SWT 1
S Swing Mal wieder JTable Ansicht aktualisieren AWT, Swing, JavaFX & SWT 10
A JTable mit Daten füllen AWT, Swing, JavaFX & SWT 1
VfL_Freak Swing Einzelne Zeile in jTable selektieren klappt nicht AWT, Swing, JavaFX & SWT 7
N AWT jTable CellRenderer AWT, Swing, JavaFX & SWT 6
T Swing JTable valueChanged datensatz löschen AWT, Swing, JavaFX & SWT 1
0 Swing JTable aus anderer Klasse updaten AWT, Swing, JavaFX & SWT 5
S Jtable defaultRenderer wohin damit ? AWT, Swing, JavaFX & SWT 23
T Swing JTable / FocusListener AWT, Swing, JavaFX & SWT 0
it_is_all Warum wird die JTable im JDialog nicht angezeigt? AWT, Swing, JavaFX & SWT 1
L Swing JTable im Panel darstellen AWT, Swing, JavaFX & SWT 8
T Swing Double Click bei Buttons in JTable AWT, Swing, JavaFX & SWT 9
J addRow bei JTable AWT, Swing, JavaFX & SWT 6
M Jtable gibt -1 wert bei selectedRow und Column AWT, Swing, JavaFX & SWT 3
Meeresgott Swing JTable AWT, Swing, JavaFX & SWT 4
J JTable Selection Listener funktioniert nicht AWT, Swing, JavaFX & SWT 4
C Swing Daten in JTable wiedergeben per TableModel und MVC Pattern AWT, Swing, JavaFX & SWT 16
Z Swing Drag&Drop zwischen JTable und JTree AWT, Swing, JavaFX & SWT 4
Thallius JTable dynamisch Spaltenanzahl verändern AWT, Swing, JavaFX & SWT 2
Thallius JTable dynamisch laden? AWT, Swing, JavaFX & SWT 2
B Swing JTable sortieren AWT, Swing, JavaFX & SWT 2
T Swing JTable auslesen und befüllen AWT, Swing, JavaFX & SWT 8
B JTable wird nicht angezeigt AWT, Swing, JavaFX & SWT 1
J JTable und Suchlogik AWT, Swing, JavaFX & SWT 4
Viktim Swing JTable mit Tab verlassen AWT, Swing, JavaFX & SWT 1
F Swing Spaltenbreite einer Column eines JTable auslesen AWT, Swing, JavaFX & SWT 5
Viktim Swing JTable Mit Tab druch Zeilen Wechseln AWT, Swing, JavaFX & SWT 5
Thallius Warum refrehsed mein JTable nicht? AWT, Swing, JavaFX & SWT 5
Ghostman1711 Hinzufügen ausgewählter Dateinen des Filechoosers zu einem JTable AWT, Swing, JavaFX & SWT 9
S Swing JTable - Einzelne Rows einfärben AWT, Swing, JavaFX & SWT 11
M Wert einer Zelle aus JTable ziehen AWT, Swing, JavaFX & SWT 4
K JTable getValueAt() klappt nicht immer AWT, Swing, JavaFX & SWT 1
K JTable in extra Klasse, Zugriff in einer anderen klasse nicht möglich AWT, Swing, JavaFX & SWT 26
B Swing Tabelle(JTable) filtern swing GUI AWT, Swing, JavaFX & SWT 3
P JTable - bei Eingabe Selektion AWT, Swing, JavaFX & SWT 0
P Fokus auf Zelle in JTable AWT, Swing, JavaFX & SWT 1
S Swing Deselektion in JTable verhindern AWT, Swing, JavaFX & SWT 0
D Problem mit JTable AWT, Swing, JavaFX & SWT 1
N Swing Print JTable mit AbstractTableModel AWT, Swing, JavaFX & SWT 1
Ananaskirsche Swing jTable Reihen zuviel eingefügt AWT, Swing, JavaFX & SWT 12
P im JTable die Schriftfarbe ändern AWT, Swing, JavaFX & SWT 19
T Swing JTable wird nicht angezeigt AWT, Swing, JavaFX & SWT 4
S Dreiecke in bestimmte Zellen einer JTable AWT, Swing, JavaFX & SWT 9
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
D Swing JTable Renderer Grafikfehler AWT, Swing, JavaFX & SWT 0
K Swing JTable mit ImageIcon und Text in einer Zelle AWT, Swing, JavaFX & SWT 1
M Swing JTable GroupableHeader Background Color AWT, Swing, JavaFX & SWT 4
K Swing JTable updaten AWT, Swing, JavaFX & SWT 9
thet1983 Swing MySQL >> JTable AWT, Swing, JavaFX & SWT 5
J JTable bounds ändern durch resizing des Fensters AWT, Swing, JavaFX & SWT 9
F JTable Zellen-Hintergrund ändern AWT, Swing, JavaFX & SWT 7
O JTable linksbündig drucken (nicht der Zelleninhalt) AWT, Swing, JavaFX & SWT 2
Crazynet xls Datei in JTable AWT, Swing, JavaFX & SWT 3
O JTable ohne Rahmen printen AWT, Swing, JavaFX & SWT 3
L Swing JTable refresht die Column Namen nicht AWT, Swing, JavaFX & SWT 0
K JTable komplett durch andere ersetzen AWT, Swing, JavaFX & SWT 4
S JTable übernimmt Änderungen nicht AWT, Swing, JavaFX & SWT 2
Y JTable AWT, Swing, JavaFX & SWT 6

Ähnliche Java Themen


Oben