JTableの列ヘッダーを強調表示します -- java フィールド と swing フィールド と jtable フィールド と highlight フィールド と jtableheader フィールド 関連 問題

Highlighting a column header of a JTable












6
vote

問題

日本語

現在は少しJTableを構築し、このセルで関連する名前を見つけやすくするために、セルが選択されているときに、列ヘッダー(および行ヘッダー部分が実際に機能しています)を強調表示したいです。 。ここに写真:

です

ENTER IMART___________P> <p>私はすでにこれを使ってヘッダーのレンダラーを切り替えようとしました:</p> <事前> <コード> table.getTableHeader().setDefaultRenderer(new ColumnHeaderRenderer());  </コード> </PRE> <p>しかし、私がヘッダーをクリックしたときにのみ呼び出され、常にISSElectedがfalseであると常に言います。 </p> <P>これは、レンダラの内部のハイライトを含む行名に使用するコードです - コードは私にはありません、私はそれを少し変更しました:</p> <事前> <コード> /*  *  Use a JTable as a renderer for row numbers of a given main table.  *  This table must be added to the row header of the scrollpane that  *  contains the main table.  */ public class RowNameTable extends JTable         implements ChangeListener, PropertyChangeListener {      private JTable main;      public RowNameTable(JTable table) {         main = table;         main.addPropertyChangeListener(this);          setFocusable(false);         setAutoCreateColumnsFromModel(false);         setModel(main.getModel());         setSelectionModel(main.getSelectionModel());          TableColumn column = new TableColumn();         column.setHeaderValue(

そしてここではテーブルを作成するための関連部分があります。

<事前> <コード> costTableModel = new CostTableModel(costCalc); table = new JTable(costTableModel); table.setPreferredScrollableViewportSize(table.getPreferredSize()); table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); table.setCellSelectionEnabled(true); scrollPane = new JScrollPane(table); RowNameTable nameTable = new RowNameTable(table); scrollPane.setRowHeaderView(nameTable);

とクラスのCostTableModel、完全性のために:

<事前> <コード> public class CostTableModel extends AbstractTableModel { private CostCalculator costCalc; public CostTableModel(CostCalculator costCalc) { this.costCalc = costCalc; } @Override public int getRowCount() { return costCalc.getPersonsList().size(); } @Override public int getColumnCount() { return costCalc.getPersonsList().size(); } @Override public String getColumnName(int col) { return costCalc.getPersonsList().get(col).getName(); } @Override public Object getValueAt(int rowIndex, int columnIndex) { Person debtor = costCalc.getPersonsList().get(rowIndex); Person debtee = costCalc.getPersonsList().get(columnIndex); return costCalc.getAmountOwed(debtor, debtee); } @Override public Class getColumnClass(int c) { return getValueAt(0, c).getClass(); } }

事前にあなたの助けをありがとう!

英語

i'm currently building a little JTable, and want to highlight the column header (and row headers - the row-header part is actually working) when a cell is selected to make it easier to find the associated names with this cell. Here is a picture:

enter image description here

I already tried switching out the renderer for the header with this:

table.getTableHeader().setDefaultRenderer(new ColumnHeaderRenderer()); 

But it's only called when i click on the header and always says isSelected is false.

This is the code i use for the row-names, including the highlight inside the renderer - code is not by me, i just modified it a little:

/*  *  Use a JTable as a renderer for row numbers of a given main table.  *  This table must be added to the row header of the scrollpane that  *  contains the main table.  */ public class RowNameTable extends JTable         implements ChangeListener, PropertyChangeListener {      private JTable main;      public RowNameTable(JTable table) {         main = table;         main.addPropertyChangeListener(this);          setFocusable(false);         setAutoCreateColumnsFromModel(false);         setModel(main.getModel());         setSelectionModel(main.getSelectionModel());          TableColumn column = new TableColumn();         column.setHeaderValue(" ");         addColumn(column);         column.setCellRenderer(new RowNameRenderer(main));          getColumnModel().getColumn(0).setPreferredWidth(table.getColumnModel().getColumn(0).getPreferredWidth());         setPreferredScrollableViewportSize(getPreferredSize());     }      @Override     public void addNotify() {         super.addNotify();          Component c = getParent();          //  Keep scrolling of the row table in sync with the main table.          if (c instanceof JViewport) {             JViewport viewport = (JViewport) c;             viewport.addChangeListener(this);         }     }      /*      *  Delegate method to main table      */     @Override     public int getRowCount() {         return main.getRowCount();     }      @Override     public int getRowHeight(int row) {         return main.getRowHeight(row);     }      /*      *  This table does not use any data from the main TableModel,      *  so just return a value based on the row parameter.      */     @Override     public Object getValueAt(int row, int column) {         return Integer.toString(row + 1);     }      /*      *  Don't edit data in the main TableModel by mistake      */     @Override     public boolean isCellEditable(int row, int column) {         return false;     } // //  Implement the ChangeListener //      public void stateChanged(ChangeEvent e) {         //  Keep the scrolling of the row table in sync with main table          JViewport viewport = (JViewport) e.getSource();         JScrollPane scrollPane = (JScrollPane) viewport.getParent();         scrollPane.getVerticalScrollBar().setValue(viewport.getViewPosition().y);     } // //  Implement the PropertyChangeListener //      public void propertyChange(PropertyChangeEvent e) {         //  Keep the row table in sync with the main table          if ("selectionModel".equals(e.getPropertyName())) {             setSelectionModel(main.getSelectionModel());         }          if ("model".equals(e.getPropertyName())) {             setModel(main.getModel());         }     }      /*      *  Borrow the renderer from JDK1.4.2 table header      */     private static class RowNameRenderer extends DefaultTableCellRenderer {          private JTable main;          public RowNameRenderer(JTable main) {             this.main = main;             setHorizontalAlignment(JLabel.CENTER);         }          @Override         public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {             if (table != null) {                 JTableHeader header = table.getTableHeader();                  if (header != null) {                     setForeground(header.getForeground());                     setBackground(header.getBackground());                     setFont(header.getFont());                 }             }              if (isSelected) {                 setFont(getFont().deriveFont(Font.BOLD));             }              setText((value == null) ? "" : main.getColumnName(row));             setBorder(UIManager.getBorder("TableHeader.cellBorder"));              return this;         }     } } 

And here we have the relevant part to create the table:

    costTableModel = new CostTableModel(costCalc);     table = new JTable(costTableModel);     table.setPreferredScrollableViewportSize(table.getPreferredSize());     table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);     table.setCellSelectionEnabled(true);      scrollPane = new JScrollPane(table);      RowNameTable nameTable = new RowNameTable(table);     scrollPane.setRowHeaderView(nameTable); 

And the class costTableModel, just for completeness sake:

public class CostTableModel extends AbstractTableModel {     private CostCalculator costCalc;      public CostTableModel(CostCalculator costCalc) {         this.costCalc = costCalc;     }      @Override     public int getRowCount() {         return costCalc.getPersonsList().size();     }      @Override     public int getColumnCount() {         return costCalc.getPersonsList().size();     }      @Override     public String getColumnName(int col) {         return costCalc.getPersonsList().get(col).getName();     }      @Override     public Object getValueAt(int rowIndex, int columnIndex) {         Person debtor = costCalc.getPersonsList().get(rowIndex);         Person debtee = costCalc.getPersonsList().get(columnIndex);          return costCalc.getAmountOwed(debtor, debtee);     }      @Override     public Class getColumnClass(int c) {         return getValueAt(0, c).getClass();      } } 

Thank you for your help in advance!

</div
              

回答リスト

5
 
vote
vote
ベストアンサー
 

基本的な問題は、テーブルヘッダーと選択変更の間の接続はありませんでした。実際、ヘッダーは本当に巧妙なものです...

私は自分のヘッダーを提供しました。これはテーブルの選択モデルにリスナーを添付し、選択された選択にヘッダーを再描画しました。

<事前> <コード> import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.EventQueue; import java.util.List; import javax.swing.Icon; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.RowSorter; import javax.swing.RowSorter.SortKey; import static javax.swing.SortOrder.ASCENDING; import static javax.swing.SortOrder.DESCENDING; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader; public class TestColumnHighlight { public static void main(String[] args) { new TestColumnHighlight(); } public TestColumnHighlight() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JTable table = new JTable(); DefaultTableModel model = new DefaultTableModel( new Object[]{"abc", "def", "ghi", "jkl"}, 0); model.addRow(new Object[]{0, 0, 0, 0}); model.addRow(new Object[]{0, 0, 0, 0}); model.addRow(new Object[]{0, 0, 0, 0}); model.addRow(new Object[]{0, 0, 0, 0}); model.addRow(new Object[]{0, 0, 0, 0}); table.setModel(model); table.setTableHeader(new CustomTableHeader(table)); table.getTableHeader().setDefaultRenderer(new ColumnHeaderRenderer()); JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new JScrollPane(table)); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class CustomTableHeader extends JTableHeader { public CustomTableHeader(JTable table) { super(); setColumnModel(table.getColumnModel()); table.getColumnModel().getSelectionModel().addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { repaint(); } }); } @Override public void columnSelectionChanged(ListSelectionEvent e) { repaint(); } } public class ColumnHeaderRenderer extends DefaultTableHeaderCellRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean selected, boolean focused, int row, int column) { super.getTableCellRendererComponent(table, value, selected, focused, row, column); int selectedColumn = table.getSelectedColumn(); System.out.println("Selected " + selectedColumn + "-" + column); if (selectedColumn == column) { Color bg = table.getSelectionBackground(); setBackground(bg); setOpaque(true); } else { setOpaque(false); } return this; } } public class DefaultTableHeaderCellRenderer extends DefaultTableCellRenderer { public DefaultTableHeaderCellRenderer() { setHorizontalAlignment(CENTER); setHorizontalTextPosition(LEFT); setVerticalAlignment(BOTTOM); setOpaque(false); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); JTableHeader tableHeader = table.getTableHeader(); if (tableHeader != null) { setForeground(tableHeader.getForeground()); } setIcon(getIcon(table, column)); setBorder(UIManager.getBorder("TableHeader.cellBorder")); return this; } protected Icon getIcon(JTable table, int column) { SortKey sortKey = getSortKey(table, column); if (sortKey != null && table.convertColumnIndexToView(sortKey.getColumn()) == column) { switch (sortKey.getSortOrder()) { case ASCENDING: return UIManager.getIcon("Table.ascendingSortIcon"); case DESCENDING: return UIManager.getIcon("Table.descendingSortIcon"); } } return null; } protected SortKey getSortKey(JTable table, int column) { RowSorter rowSorter = table.getRowSorter(); if (rowSorter == null) { return null; } List sortedColumns = rowSorter.getSortKeys(); if (sortedColumns.size() > 0) { return (SortKey) sortedColumns.get(0); } return null; } } }
 

The basic issue I had was there was no connection between the table header and the selection change. In fact, the header is really clever with it's repaints...

I ended up providing my own header, which attached a listener to the table's selection model and repainted the header on the selection changed.

import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.EventQueue; import java.util.List; import javax.swing.Icon; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.RowSorter; import javax.swing.RowSorter.SortKey; import static javax.swing.SortOrder.ASCENDING; import static javax.swing.SortOrder.DESCENDING; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableModel; import javax.swing.table.JTableHeader;  public class TestColumnHighlight {      public static void main(String[] args) {         new TestColumnHighlight();     }      public TestColumnHighlight() {         EventQueue.invokeLater(new Runnable() {             @Override             public void run() {                 try {                     UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());                 } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {                 }                  JTable table = new JTable();                 DefaultTableModel model = new DefaultTableModel(                                 new Object[]{"abc", "def", "ghi", "jkl"},                                 0);                  model.addRow(new Object[]{0, 0, 0, 0});                 model.addRow(new Object[]{0, 0, 0, 0});                 model.addRow(new Object[]{0, 0, 0, 0});                 model.addRow(new Object[]{0, 0, 0, 0});                 model.addRow(new Object[]{0, 0, 0, 0});                  table.setModel(model);                 table.setTableHeader(new CustomTableHeader(table));                 table.getTableHeader().setDefaultRenderer(new ColumnHeaderRenderer());                  JFrame frame = new JFrame("Testing");                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);                 frame.setLayout(new BorderLayout());                 frame.add(new JScrollPane(table));                 frame.pack();                 frame.setLocationRelativeTo(null);                 frame.setVisible(true);             }         });     }      public class CustomTableHeader extends JTableHeader {          public CustomTableHeader(JTable table) {             super();             setColumnModel(table.getColumnModel());             table.getColumnModel().getSelectionModel().addListSelectionListener(new ListSelectionListener() {                 @Override                 public void valueChanged(ListSelectionEvent e) {                     repaint();                 }             });         }          @Override         public void columnSelectionChanged(ListSelectionEvent e) {             repaint();         }      }      public class ColumnHeaderRenderer extends DefaultTableHeaderCellRenderer {          @Override         public Component getTableCellRendererComponent(JTable table, Object value, boolean selected, boolean focused, int row, int column) {             super.getTableCellRendererComponent(table, value, selected, focused, row, column);              int selectedColumn = table.getSelectedColumn();             System.out.println("Selected " + selectedColumn + "-" + column);             if (selectedColumn == column) {                 Color bg = table.getSelectionBackground();                 setBackground(bg);                 setOpaque(true);             } else {                 setOpaque(false);             }              return this;         }      }      public class DefaultTableHeaderCellRenderer extends DefaultTableCellRenderer {          public DefaultTableHeaderCellRenderer() {             setHorizontalAlignment(CENTER);             setHorizontalTextPosition(LEFT);             setVerticalAlignment(BOTTOM);             setOpaque(false);         }          @Override         public Component getTableCellRendererComponent(JTable table, Object value,                         boolean isSelected, boolean hasFocus, int row, int column) {             super.getTableCellRendererComponent(table, value,                             isSelected, hasFocus, row, column);             JTableHeader tableHeader = table.getTableHeader();             if (tableHeader != null) {                 setForeground(tableHeader.getForeground());             }             setIcon(getIcon(table, column));             setBorder(UIManager.getBorder("TableHeader.cellBorder"));             return this;         }          protected Icon getIcon(JTable table, int column) {             SortKey sortKey = getSortKey(table, column);             if (sortKey != null && table.convertColumnIndexToView(sortKey.getColumn()) == column) {                 switch (sortKey.getSortOrder()) {                     case ASCENDING:                         return UIManager.getIcon("Table.ascendingSortIcon");                     case DESCENDING:                         return UIManager.getIcon("Table.descendingSortIcon");                 }             }             return null;         }          protected SortKey getSortKey(JTable table, int column) {             RowSorter rowSorter = table.getRowSorter();             if (rowSorter == null) {                 return null;             }              List sortedColumns = rowSorter.getSortKeys();             if (sortedColumns.size() > 0) {                 return (SortKey) sortedColumns.get(0);             }             return null;         }     } } 
</div
 
 
         
         
8
 
vote

わずかな変形:私が質問を読み取ると、主な問題は選択変更で更新されていないヘッダーです。カスタムヘッダを row の選択変更を聴くことは、そのシナリオの場合はあまり役に立ちません。

実際には、はであるがColumnModelを聴取し、モデルの変更通知には選択変更が含まれています。 ColumnSelectionChangeメソッドのみが意図的に何もしないことを意図的に実装されています。

<事前> <コード> // --Redrawing the header is slow in cell selection mode. // --Since header selection is ugly and it is always clear from the // --view which columns are selected, don't redraw the header.

カスタムヘッダーは簡単に実装することができます(ここでは、テーブルの工場の方法では、テーブルの工場の方法で行います。 <事前> <コード> final JTable table = new JTable(new AncientSwingTeam()) { @Override protected JTableHeader createDefaultTableHeader() { // subclassing to take advantage of super's auto-wiring // as ColumnModelListener JTableHeader header = new JTableHeader(getColumnModel()) { @Override public void columnSelectionChanged(ListSelectionEvent e) { repaint(); } }; return header; } }; table.setCellSelectionEnabled(true); table.getTableHeader().setDefaultRenderer(new ColumnHeaderRenderer());

テーブルAPIを使用してMADのレンダラーを少し微調整しました:

<事前> <コード> /** * Slightly adjusted compared to @Mad * - use table's selectionBackground * - use table's isColumnSelected to decide on highlight */ public static class ColumnHeaderRenderer extends DefaultTableCellHeaderRenderer { @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean selected, boolean focused, int row, int column) { super.getTableCellRendererComponent(table, value, selected, focused, row, column); if (table.isColumnSelected(column)) { setBackground(table.getSelectionBackground()); } return this; } }

観察に関して:

isselectedがfalse

理由は、基本ヘッディーのわずかなQUIRKです:

<事前> <コード> ui.selected != columnModel.selected

uiselectedはkeybindingsからアクセス可能な列です - LAFがそれをサポートし、ヘッダーがフォーカスウォーカーである場合私には本当に意味がありませんが、UIとColumnModelの選択の意味を完全に定義し、それは忘れられています。 - )

 

A slight variant: as I read the question, the main problem is the header not updating on column selection change. Having a custom header listen to row selection changes doesn't help much for that scenario.

In fact, a JTableHeader already is listening to the ColumnModel and the model's change notification includes selection changes. Only the columnSelectionChange method is intentionally implemented to do nothing:

// --Redrawing the header is slow in cell selection mode. // --Since header selection is ugly and it is always clear from the // --view which columns are selected, don't redraw the header. 

A custom header can simply implement to repaint (here lazy me does it in the table's factory method just to spare me the wiring to the table, you can easily make it a stand-alone class :-).

final JTable table = new JTable(new AncientSwingTeam()) {      @Override     protected JTableHeader createDefaultTableHeader() {         // subclassing to take advantage of super's auto-wiring         // as ColumnModelListener         JTableHeader header = new JTableHeader(getColumnModel()) {              @Override             public void columnSelectionChanged(ListSelectionEvent e) {                 repaint();             }          };         return header;     }  }; table.setCellSelectionEnabled(true); table.getTableHeader().setDefaultRenderer(new ColumnHeaderRenderer()); 

Also tweaked Mad's renderer a bit, using table api:

/**  * Slightly adjusted compared to @Mad  * - use table's selectionBackground  * - use table's isColumnSelected to decide on highlight  */ public static class ColumnHeaderRenderer extends DefaultTableCellHeaderRenderer {      @Override     public Component getTableCellRendererComponent(JTable table, Object value, boolean selected,           boolean focused, int row, int column) {         super.getTableCellRendererComponent(table, value, selected, focused, row, column);          if (table.isColumnSelected(column)) {             setBackground(table.getSelectionBackground());         }         return this;     } } 

As to the observation:

always says isSelected is false

The reason is a slight quirk in BasicTableHeaderUI:

ui.selected != columnModel.selected 

uiSelected is the column which will be accessible to keybindings - if the laf supports it and the header is focusOwner. Doesn't really make sense to me, but fully defining the semantics of ui and columnModel selection fell into the excitement about the new babe fx, that is got forgotten ;-)

</div
 
 
   
   

関連する質問

8  JTableで列ヘッダーを設定します  ( Setting column headers in jtable ) 
表モデルを使用する次のJTableを持っています: > http://s17.postimage.org/7ZFH3L4 / SCREEN_SHOT_2012_03_10_AT_15_11_31.PNG < / P> 使用する代わりに、A、B、C、Dなど、...

0  JTableの各列のヘッダーを決定する  ( Determining the header of each column in a jtable ) 
6行8列のJTableを作成しました。列ごとにヘッダーを設定します。私はコードをベローズにしました、そしてそれは私のためにうまくいきませんでした。 <事前> <コード> JTable apartma = new JTable(6,8); a...

0  テキストをテーブルなしでJTableHeaderに関連付けることができますか?  ( Is possible to associate a text to a jtableheader without a table ) 
いくつかのセル内のヘッダーを使ってJTableを作成したいです。しかし、私はこのヘッダーとテキストを関連付けたいです。出来ますか?どうやってやるの? すべての私の最高! Leandro Lima ...

1  JTableHeaderの外観と感触と色を設定する方法  ( How to set jtableheader look and feel and color ) 
これは私の最初の投稿ですので、私のポストをよりよくする方法についての提案は素晴らしいです! このウェブサイトからの研究の助けを借りて、私は現在の外観を変更し、現在の外観を維持し、維持することができる表を生成することができます。ただし、色を変えることができず、何...

0  JTableで列のActionListenerを追加する  ( Adding actionlistener of column in a jtable ) 
こんにちは.. もう一度助けが必要です。 :) これを行う方法?列T1をクリックすると、別のフォームは、列T1への何が起こるかを説明する必要があります。つまり、命令1がフェッチステージにある。次に、ナミャンT2列をクリックすると、命令2はフェッチステージ...

1  Java Jtableヘッドが表示されていません  ( Java jtable head not showing ) 
ボタンをクリックすると、パネルに表示したいテーブルがあります。私はテーブルを表示することができますが、私はヘッダーが表示することができません。 JScrollPaneを使用してみましたが、ここでは全くUPSを表示していません。 コードの主要部分: パブリックク...

18  JTableのヘッダーのフォントを変更するにはどうすればよいですか。  ( How can i change the font of a jtables header ) 
JTableヘッダーのフォントを設定します。 あなたはどのように? ...

0  列に名前を付けます。  ( How to put name to columns to one jtable ) 
<事前> <コード> file1 私はクエリで私のJtableを埋めるための方法がありますが、Jtable '列に名前がありません、どうすればよいですか?照らされたクエリを削除したくはありません。 ...

16  JTableヘッダーの高さを変更する方法  ( How to change jtable header height ) 
タイトルは質問を説明します。どのように私は簡単にそれをすることができますか? ...

0  JPAnelをJTableでヘッダーに追加する方法はありますか? [閉まっている]  ( Is there any way to add a jpanel to a header in a jtable ) 
ここで尋ねられていることを知るのは難しいです。この問題はあいまい、曖昧で、不完全で、過度に広く、または修辞的であり、現在の形で合理的に回答することはできません。再開できるようにこの質問を...




© 2022 cndgn.com All Rights Reserved. Q&Aハウス 全著作権所有