Swing JTable Header modifizieren

Status
Nicht offen für weitere Antworten.

freaki_333

Mitglied
Hi,

ich hab eine Frage. Und zwar soll ich eine Tabelle Programmieren welches im Header ein ComboBox intergriert sein soll.
Da ich ein Realtiver Neuling in Java bzw Swing bin, weiß ich net wo ich ansetzen soll.
Wär hilfreich wenn ihr mir nen Denkanstoß geben könntet.


---------------
| Label
|Combobox
---------------

gruß freaki
 

freaki_333

Mitglied
Morgen,

Hi danke für die Antwort aber das ist nicht was ich suche. bzw. ich hab bei google auch nix gefunden.
Es sollte wie auf der skizze sein. Ein Label oben darunter eine ComboBox und das ganze im Header.
Weiß jemand rat?

Gruß freaki
 

Michael...

Top Contributor
Der Header einer JTable besitzt nur einen Renderer. Dein Vorhaben ist deshalb so ohne weiteres nicht umsetzbar. Man kann zwar so einen Renderer schreiben der eine Label und eine Combobox darstellt, aber bedienen kann man sie dann nicht. Mein Vorschlag wäre das über ein Popupmenü zu lösen.
 

mr-gurke

Mitglied
Das würde mich wundern, wenn das nicht ginge.

Du kannst dir deinen eigenen TableCellRenderer für den Header basteln.
Dazu schreibst du dir eine Klasse, die das Interface TableCellRenderer implementiert.
Java:
Component getTableCellRendererComponent(JTable table,
                                        Object value,
                                        boolean isSelected,
                                        boolean hasFocus,
                                        int row,
                                        int column);
Diese Methode musst du dann so ausprogrammieren, dass ein Panel mit den Inhalten, die du willst zurückgeliefert wird.
Da die Methode weiß, um welche Spalte es sich handelt, kannst du auch jede Header Spalte anders darstellen.

Bedienen kannst du das dann auch, du kannst in deinem Renderer ja die entsprechenden ActionListener an deinen Objekten registrieren.
 

Michael...

Top Contributor
Bedienen kannst du das dann auch, du kannst in deinem Renderer ja die entsprechenden ActionListener an deinen Objekten registrieren.
Das würde mich jetzt wundern.
Man kann dem Header einen Renderer übergeben, damit er so ausschaut wie eine Kombination aus Label und ComboBox. Wenn man die ComboBox tatsächlich nutzen wollte bräuchte man einen Editor und das gibts für einen JTableHeader nicht.
 

mr-gurke

Mitglied
Tatsache, du hast recht. Überrascht mich jetzt aber schon ein bisschen. Sonst kann bei Swing ja immer jeder alles. Aber die Comboboxen sind blockiert ...
Java:
public class JTableTest {

	private static JLabel label;


	public static void main(String[] args){
		//Beispiel aus der Java Insel
		label = new JLabel("noch nix passiert");
		String[][] rowData = {
				{ "Japan", "245" }, { "USA", "240" }, { "Italien", "220" },
				{ "Spanien", "217" }, {"Türkei", "215"} ,{ "England", "214" },
				{ "Frankreich", "190" }, {"Griechenland", "185" },
				{ "Deutschland", "180" }, {"Portugal", "170" }
		};
		String[] columnNames = {
				"Land", "Durchschnittliche Sehdauer pro Tag in Minuten"
		};
		JFrame f = new JFrame();
		f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
		JTable table = new JTable( rowData, columnNames );
		table.getTableHeader().setDefaultRenderer(new TableCellRenderer() {

			@Override
			public Component getTableCellRendererComponent(JTable table,
					Object value, boolean isSelected, boolean hasFocus, int row,
					int column) {
				JPanel headerPanel = new JPanel();
				headerPanel.setLayout(new FlowLayout());
				JComboBox box = new JComboBox();
				final ComboBoxModel boxModel = new DefaultComboBoxModel(new Object[] {"Option 1", "Option 2", "Option 3"});
				box.setModel(boxModel);
				box.addPropertyChangeListener(new PropertyChangeListener() {
					@Override
					public void propertyChange(PropertyChangeEvent event) {
						label.setText(boxModel.getSelectedItem().toString());
					}});
				headerPanel.add(new JLabel("Spalte " + column));
				headerPanel.add(box);
				return headerPanel;
			}});

		f.setLayout(new FlowLayout());
		f.add( new JScrollPane(table));
		f.add(label);
		f.pack();
		f.setVisible( true );

	}
}

@freaki_333: Als Workaround kannst du den Header für dein Label verwenden und missbrauchst einfach die erste Tabellenzeile für die Combobox.
 

Ebenius

Top Contributor
Tipp am Rande: Wann auch immer in Swing das Wort "Renderer" auftaucht, ist dieser tot. Er wird -- in der Regel über eine CellRendererPane -- gezeichnet und danach vergessen. Immer wenn man "Renderer" liest, sollte man nachschauen, ob in der Nähe irgendwie das Wort "Editor" auftaucht. Im Falle des JTableHeaders ist dies nicht der Fall, der kann von Hause aus nur darstellen.

Ebenius
 

freaki_333

Mitglied
Hi,

hat keiner eine Idee wie ich das umsetzen kann. Ich muss die ComboBox im Header einbauen, in der erste Reihe der Tabelle darf ich das nicht machen.


Gruß freaki
 
S

SlaterB

Gast
wieso musst du das und wieso so einsilbig?
ist das für einen Kunden ohne Java-Kenntnisse?
dann sollte doch das JOptionPane, wie in meinem Link beschrieben, ausreichen
 

Michael...

Top Contributor
Die ComboBox benutzt ja auch nur ein Popupmenü. Was spricht gegen mein Vorschlag sich selber ein Popup zu basteln und dann per Mouseclick im Header anzeigen zu lassen? Der Anwender merkt da kaum, wenn überhaupt, einen Unterschied.
 

freaki_333

Mitglied
Hi,

ja muss das für ein Kunden Programmieren und dieser will es genau so haben wie in der vorherigen Version des Programmes. Aber die vorherige Version haben wir nicht programmiert. Und da ich keine Ahnung habe wo ich ansetzen soll für ich bin am verzweifeln.


Gruß freaki
 

Ebenius

Top Contributor
Hier hast Du was zum spielen. Ist nur eine Möglichkeit, das ganze zu Lösen.

Java:
/* (@)JTableHeaderComboBoxDemo.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. */

import java.awt.*;
import java.util.HashMap;
import java.util.Map;

import javax.swing.*;
import javax.swing.event.TableColumnModelEvent;
import javax.swing.table.*;

/**
 * A table header with one combo box for each column.
 * 
 * @author Sebastian Haufe
 */
public class JTableHeaderComboBoxDemo {

  /**
   * Extended table header, adding the preferred height of the layout to its
   * preferred height and revalidates when the dragged column is released.
   */
  private static class JXTableHeader extends JTableHeader {

    JXTableHeader(TableColumnModel cm) {
      super(cm);
    }

    @Override
    public Dimension getPreferredSize() {
      final Dimension size = super.getPreferredSize();
      final LayoutManager layout = getLayout();
      if (layout != null) {
        size.height += layout.preferredLayoutSize(this).height;
      }
      return size;
    }

    @Override
    public void columnMoved(TableColumnModelEvent e) {
      super.columnMoved(e);
      if (getDraggedColumn() != null) {
        revalidate();
        repaint();
      }
    }

    @Override
    public void setDraggedColumn(TableColumn column) {
      super.setDraggedColumn(column);
      if (column == null) {
        revalidate();
        repaint();
      }
    }
  }

  /**
   * Layout for table header. Manages components on the table header, using
   * the component index as index in the table model! Calculates the preferred
   * size with a width of zero and a height of the maximum preferred height of
   * all components. Lays out the components in their header rectangle, using
   * an additional margin.
   */
  private static final class TableHeaderSouthLayout
    implements LayoutManager2, java.io.Serializable {

    private Insets margin = new Insets(1, 1, 1, 1);
    private final Map<Component, Integer> components =
          new HashMap<Component, Integer>();

    /**
     * Get the cell margin.
     * 
     * @return the cell margin
     */
    public Insets getMargin() {
      return margin;
    }

    /**
     * Set the cell margin.
     * 
     * @param m the margin
     * @throws IllegalArgumentException if {@code margin} is {@code null}
     */
    public void setMargin(Insets m) {
      if (m == null) {
        throw new IllegalArgumentException( //
              "margin not allowed null"); //$NON-NLS-1$
      }
      this.margin = new Insets(m.top, m.left, m.bottom, m.right);
    }

    public void layoutContainer(Container parent) {
      final JTableHeader th = ((JTableHeader) parent);
      final JTable table = th.getTable();
      final int componentCount = th.getComponentCount();
      for (int i = 0; i < componentCount; i++) {
        final Component comp = th.getComponent(i);
        final Integer columnIndexObj = components.get(comp);
        final int colIndex;
        final int viewIndex;
        if (table == null
              || columnIndexObj == null
              || (colIndex = columnIndexObj.intValue()) < 0
              || (viewIndex = table.convertColumnIndexToView(colIndex)) < 0
              || viewIndex >= table.getColumnCount()) {
          comp.setBounds(0, 0, 0, 0);
        } else {
          final Rectangle rect = th.getHeaderRect(viewIndex);
          final TableColumn draggedColumn = th.getDraggedColumn();
          if (draggedColumn != null
                && draggedColumn.getModelIndex() == colIndex) {
            rect.x += th.getDraggedDistance();
            th.setComponentZOrder(comp, 0);
          }
          rect.x += margin.left;
          rect.y += margin.top;
          rect.width -= margin.left + margin.right;
          rect.height -= margin.top + margin.bottom;
          final Dimension size = comp.getPreferredSize();
          if (rect.height > size.height) {
            rect.y += rect.height - size.height;
            rect.height = size.height;
          }
          comp.setBounds(rect);
        }
      }
    }

    public Dimension preferredLayoutSize(Container parent) {
      final JTableHeader th = ((JTableHeader) parent);
      final JTable table = th.getTable();
      final int componentCount = th.getComponentCount();
      int h = 0;
      for (int i = 0; i < componentCount; i++) {
        final Component comp = th.getComponent(i);
        final Integer columnIndexObj = components.get(comp);
        final int colIndex;
        final int viewIndex;
        if (table != null
              && columnIndexObj != null
              && (colIndex = columnIndexObj.intValue()) >= 0
              && (viewIndex = table.convertColumnIndexToView(colIndex)) >= 0
              && viewIndex < table.getColumnCount()) {
          h = Math.max(h, comp.getPreferredSize().height);
        }
      }
      return new Dimension(0, margin.top + margin.bottom + h);
    }

    public Dimension minimumLayoutSize(Container parent) {
      return new Dimension();
    }

    public Dimension maximumLayoutSize(Container target) {
      return new Dimension();
    }

    public void removeLayoutComponent(Component comp) {
      components.remove(comp);
    }

    public void addLayoutComponent(Component comp, Object constraints) {
      if (!(constraints instanceof Integer)) {
        throw new IllegalArgumentException( //
              "Wrong type: Integer expected"); //$NON-NLS-1$
      }
      components.put(comp, (Integer) constraints);
    }

    public void addLayoutComponent(String name, Component comp) {}

    public float getLayoutAlignmentX(Container target) {
      return 0.5f;
    }

    public float getLayoutAlignmentY(Container target) {
      return 0.5f;
    }

    public void invalidateLayout(Container target) {}
  }

  /**
   * Test main method.
   * 
   * @param args ignored
   */
  public static void main(String[] args) {
    /* table without auto-added table header */
    final JTable table = new JTable(100, 10);
    table.setTableHeader(new JXTableHeader(table.getColumnModel()));

    final JTableHeader th = table.getTableHeader();
    final TableCellRenderer defaultRenderer = th.getDefaultRenderer();
    if (defaultRenderer instanceof JLabel) {
      ((JLabel) defaultRenderer).setVerticalAlignment(SwingConstants.TOP);
    }
    th.setLayout(new TableHeaderSouthLayout());

    th.add(createComboBox(new String[] { "Column A" }), Integer.valueOf(0));
    th.add(createComboBox(new String[] { "Column B" }), Integer.valueOf(1));
    th.add(createComboBox(new String[] { "Column C" }), Integer.valueOf(2));
    th.add(createComboBox(new String[] { "Column D" }), Integer.valueOf(3));
    th.add(createComboBox(new String[] { "Column E" }), Integer.valueOf(4));
    th.add(createComboBox(new String[] { "Column F" }), Integer.valueOf(5));
    th.add(createComboBox(new String[] { "Column G" }), Integer.valueOf(6));
    th.add(createComboBox(new String[] { "Column H" }), Integer.valueOf(7));
    th.add(createComboBox(new String[] { "Column I" }), Integer.valueOf(8));
    th.add(createComboBox(new String[] { "Column J" }), Integer.valueOf(9));

    /* show the test frame */
    final JFrame f = new JFrame( //
          "Test Frame: JTableHeaderComboBoxDemo"); //$NON-NLS-1$
    f.setContentPane(new JScrollPane(table));
    f.pack();
    f.setLocationRelativeTo(null);
    f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    f.setVisible(true);
  }

  private static JComboBox createComboBox(final String[] data) {
    final JComboBox cb = new JComboBox(data);
    cb.setCursor(Cursor.getDefaultCursor());
    return cb;
  }
}
Happy Hacking!
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Swing JTable : Header der Spalten ergänzen mit caption (wie bei html-table) AWT, Swing, JavaFX & SWT 2
L JTable Permanent Header AWT, Swing, JavaFX & SWT 0
N Swing JTable mit Sorter: Keine Sortierung bei Klick in Header AWT, Swing, JavaFX & SWT 3
V Swing JTable Row Header AWT, Swing, JavaFX & SWT 6
P Swing In JTable Header auch an der linken Seite AWT, Swing, JavaFX & SWT 2
V JTable Header L&F AWT, Swing, JavaFX & SWT 10
O Swing JTable Header AWT, Swing, JavaFX & SWT 2
Spin JTable Header wird nicht angezeigt ohne ScrollPane AWT, Swing, JavaFX & SWT 3
A JTable Header AWT, Swing, JavaFX & SWT 3
G Swing JTable Header neu initialisieren? AWT, Swing, JavaFX & SWT 2
G JTable Multiple Row Header Example - Probleme mit der Höhe der Zellen AWT, Swing, JavaFX & SWT 4
C Swing 1spaltige JTable ohne Header AWT, Swing, JavaFX & SWT 18
hdi Swing JTable: SortKeys und Header Column Width AWT, Swing, JavaFX & SWT 5
C jtable checkbox in header / spaltenüberschrift AWT, Swing, JavaFX & SWT 4
M Problem mit funktionellem JTable Header AWT, Swing, JavaFX & SWT 5
D Swing JTable, Header und Leerzeilen AWT, Swing, JavaFX & SWT 3
R JTable Header - will links kleines icon hinzufuegen..? AWT, Swing, JavaFX & SWT 6
R Swing JTable: Eigene Zeichnung im Header AWT, Swing, JavaFX & SWT 11
C Swing JTable Header angelickt? AWT, Swing, JavaFX & SWT 4
eskimo328 JTable Zeilenumbruch im Header AWT, Swing, JavaFX & SWT 2
T 2JLabels in einen JTable Header AWT, Swing, JavaFX & SWT 2
A JTable Header + ScrollBar AWT, Swing, JavaFX & SWT 4
H JTable drucken mit Header AWT, Swing, JavaFX & SWT 4
G JTable und Header AWT, Swing, JavaFX & SWT 4
J JTable Zellen und Header AWT, Swing, JavaFX & SWT 2
D jTable Header zweizeilig? AWT, Swing, JavaFX & SWT 2
R JTable Mehrzeiliger Header zerstört JGoodies-Layout AWT, Swing, JavaFX & SWT 2
D JTable Header während Laufzeit ändern. AWT, Swing, JavaFX & SWT 3
D Jtable Header Höhe setzen ? AWT, Swing, JavaFX & SWT 2
D Header für den Row Header (JTable) AWT, Swing, JavaFX & SWT 2
O Probleme mit header von JTable AWT, Swing, JavaFX & SWT 6
L Checkbox in JTable (again), bei true Daten in Header AWT, Swing, JavaFX & SWT 7
D Mehrzeilige JTable Header AWT, Swing, JavaFX & SWT 2
N Jtable header fixieren AWT, Swing, JavaFX & SWT 2
K Kein Header in JTable ! AWT, Swing, JavaFX & SWT 8
F Die JTable und ihr Header AWT, Swing, JavaFX & SWT 5
J JTable - Header über mehrere Spalten AWT, Swing, JavaFX & SWT 3
G JTable sortieren durch click im Header AWT, Swing, JavaFX & SWT 9
J Border im Header bei JTable verändern AWT, Swing, JavaFX & SWT 3
S JTable Header AWT, Swing, JavaFX & SWT 5
K JTable - Header colspan AWT, Swing, JavaFX & SWT 7
K JTable header updated nicht immer AWT, Swing, JavaFX & SWT 5
A JTable - Header wird nicht angezeigt AWT, Swing, JavaFX & SWT 8
D JTable Header AWT, Swing, JavaFX & SWT 2
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

Ähnliche Java Themen


Oben