2013-11-19 4 views
2

Я нашел this code, чтобы создать компонент заголовка на JTable, но я не могу дать ту же границу заголовку, что и по умолчанию. Ниже приведен скриншот кода:Как указать границы заголовка флажка JTable

screenshot

Здесь Выбрать все флажок не имеет ту же границу, как столбцы 1 и 2, чтобы он выглядит по-другому. А также уровень немного ниже, чем в столбцах n.

Исходный код выглядит следующим образом: -

package com.test.check.table; 

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.event.TableModelEvent; 
import javax.swing.event.TableModelListener; 
import javax.swing.table.*; 

public class SelectAllHeaderTest { 

    private static final int BOOLEAN_COL = 2; 
    private static final Object colNames[] = {"Column 1", "Column 2", ""}; 
    private DefaultTableModel model = new DefaultTableModel(null, colNames) { 

     @Override 
     public Class<?> getColumnClass(int columnIndex) { 
      if (columnIndex == BOOLEAN_COL) { 
       return Boolean.class; 
      } else { 
       return String.class; 
      } 
     } 
    }; 
    private JTable table = new JTable(model); 

    public void create() { 
     for (int x = 1; x < 6; x++) { 
      model.addRow(new Object[]{ 
        "Row " + x + ", Col 1", "Row " + x + ", Col 2", false 
       }); 
     } 
     table.setAutoCreateRowSorter(true); 
     table.setPreferredScrollableViewportSize(new Dimension(320, 160)); 
     TableColumn tc = table.getColumnModel().getColumn(BOOLEAN_COL); 
     tc.setHeaderRenderer(new SelectAllHeader(table, BOOLEAN_COL)); 
     String newLookAndFeel = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"; 
     try { 
      UIManager.setLookAndFeel(newLookAndFeel); 
     } catch (ClassNotFoundException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (InstantiationException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IllegalAccessException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (UnsupportedLookAndFeelException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 


     JFrame f = new JFrame(); 
     f.add(new JScrollPane(table)); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new SelectAllHeaderTest().create(); 
      } 
     }); 
    } 
} 

/** 
* A TableCellRenderer that selects all or none of a Boolean column. 
* 
* @param targetColumn the Boolean column to manage 
*/ 
class SelectAllHeader extends JCheckBox implements TableCellRenderer { 

    private static final String ALL = "Select all"; 
    private static final String NONE = "Select none"; 
    private JTable table; 
    private TableModel tableModel; 
    private JTableHeader header; 
    private TableColumnModel tcm; 
    private int targetColumn; 
    private int viewColumn; 

    public SelectAllHeader(JTable table, int targetColumn) { 
     super(ALL); 
     this.table = table; 
     this.tableModel = table.getModel(); 
     if (tableModel.getColumnClass(targetColumn) != Boolean.class) { 
      throw new IllegalArgumentException("Boolean column required."); 
     } 
     this.targetColumn = targetColumn; 
     this.header = table.getTableHeader(); 
     this.tcm = table.getColumnModel(); 
     this.applyUI(); 
     this.addItemListener(new ItemHandler()); 
     header.addMouseListener(new MouseHandler()); 
     tableModel.addTableModelListener(new ModelHandler()); 
    } 

    @Override 
    public Component getTableCellRendererComponent(
     JTable table, Object value, boolean isSelected, 
     boolean hasFocus, int row, int column) { 
     return this; 
    } 

    private class ItemHandler implements ItemListener { 

     @Override 
     public void itemStateChanged(ItemEvent e) { 
      boolean state = e.getStateChange() == ItemEvent.SELECTED; 
      setText((state) ? NONE : ALL); 
      for (int r = 0; r < table.getRowCount(); r++) { 
       table.setValueAt(state, r, viewColumn); 
      } 
     } 
    } 

    @Override 
    public void updateUI() { 
     super.updateUI(); 
     applyUI(); 
    } 

    private void applyUI() { 
     this.setFont(UIManager.getFont("TableHeader.font")); 
     this.setBorder(UIManager.getBorder("TableHeader.cellBorder")); 
     this.setBackground(UIManager.getColor("TableHeader.background")); 
     this.setForeground(UIManager.getColor("TableHeader.foreground")); 
    } 

    private class MouseHandler extends MouseAdapter { 

     @Override 
     public void mouseClicked(MouseEvent e) { 
      viewColumn = header.columnAtPoint(e.getPoint()); 
      int modelColumn = tcm.getColumn(viewColumn).getModelIndex(); 
      if (modelColumn == targetColumn) { 
       doClick(); 
      } 
     } 
    } 

    private class ModelHandler implements TableModelListener { 

     @Override 
     public void tableChanged(TableModelEvent e) { 
      if (needsToggle()) { 
       doClick(); 
       header.repaint(); 
      } 
     } 
    } 

    // Return true if this toggle needs to match the model. 
    private boolean needsToggle() { 
     boolean allTrue = true; 
     boolean allFalse = true; 
     for (int r = 0; r < tableModel.getRowCount(); r++) { 
      boolean b = (Boolean) tableModel.getValueAt(r, targetColumn); 
      allTrue &= b; 
      allFalse &= !b; 
     } 
     return allTrue && !isSelected() || allFalse && isSelected(); 
    } 
} 

Из приведенного выше кода, который я попытался дать границы к заголовку CheckBox, но это не выглядело, как ожидалось (верхний и beweled границы).

Любые предложения, направленные на создание этого верхнего, будут очень благодарны.

Благодаря

ответ

1

изменить, установите L & F во время выполнения, часть Swing-объекта создается, но RootPane не обновляется с новым L & F (металл для Windows)

начало с

  • положить L & F к основному классу, public static void main(String[] args) { перед тем кодом линии SwingUtilities.invokeLater(new Runnable() {

  • тогда вы (код говорит о) остается с JToggleButton в JTableHeader

    ) leave that, will be better and nicer

    б) удалить фоновую для JToggleButton или установить opacity, изменить Borders для недекорированного JToggleButton (имитирующей клетки в JTableHeader)

  • original code posted and screenshot by @trashgod is from Mac OSX and there is used own L&F

+1

Да, поэтому я использовал 'JToggleButton' вместо' JCheckBox' в [оригинале] (http://stackoverflow.com/a/7137801/230513). – trashgod

+1

@trashgod очень хорошая нить, тогда очень легко *** (или слово есть там, английский - мой язык предпочтения) помните, ищите автора :-) – mKorbel

0

Как было предложено, я установил границу для заголовка, как

В окне рендеринга. Я изменил его, как показано ниже: -

header.setBorder (BorderFactory.createRaisedBevelBorder());

Также поместите мой код L & в статический основной метод перед запуском.

Он показывает границу в правильном направлении, и мой флажок выглядит отлично.

Большое спасибо за ваш код! Наконец, он отлично работает.