2013-05-09 23 views
2

這可能是一個模糊的查詢,所以請原諒我。複選框中的某些單元格,但不是全部,在特定的列 - JTable

定製的JTable(我修改了查詢,並將根據提供的SSCCE進行討論)。我必須創建一個JTable,以根據JTable中的選定複選框提供授權。此JTable的目的是向用戶顯示應用程序的所有菜單選項。此JTable有三列: 第一欄:類Bollean(複選框) 第二欄:String類(主菜單項) 第三欄:String類(子菜單項)

來提供授權用戶應選擇相應的複選框到子菜單項,最後選擇「授權」按鈕(我沒有包括授權按鈕,因爲我的授權功能工作正常)

現在UI要求是在JTable的第一列中,我應該顯示而不是在第一列的每個單元格中顯示覆選框(換句話說,不應顯示與主菜單項目對應的複選框)

產品圖如下預期輸出(雖然我得到的所有細胞與複選框第一列)

Expected UI

public class SwingSolution extends JPanel { 

    public SwingSolution() { 
     super(new GridLayout(1,0)); 

     String[] columnNames = {"", "Main Menu", "Sub Menu"}; 

     Object[][] data = { 
     {false, "File", ""}, 
     {false, "", "New"}, 
     {false, "", "Save"}, 
     {false, "", "Close"}, 
     {false, "Edit", ""}, 
     {false, "", "Delete"}, 
     {false, "", "Format"}, 
     {false, "Project", ""}, 
     {false, "", "Create New"}, 
     {false, "", "Delete"}, 
     {false, "", "Build"}, 
     {false, "", "Properties"}, 
     }; 

     DefaultTableModel model = new DefaultTableModel(data, columnNames); 
     final JTable table = new JTable(model) { 

      private static final long serialVersionUID = 1L; 

      @Override 
      public Class getColumnClass(int column) { 
       switch (column) { 
        case 0: 
         return Boolean.class; 
        case 1: 
         return String.class; 
        case 2: 
         return String.class; 
        default: 
         return Boolean.class; 
       } 
      } 
     }; 

     table.getColumnModel().getColumn(0).setMaxWidth(30); 
     table.getColumnModel().getColumn(1).setMaxWidth(100); 
     table.getColumnModel().getColumn(2).setMaxWidth(120); 

     table.setPreferredScrollableViewportSize(new Dimension(250, 195)); 
     table.setFillsViewportHeight(true); 

     //Create the scroll pane and add the table to it. 
     JScrollPane scrollPane = new JScrollPane(table); 

     //Add the scroll pane to this panel. 
     add(scrollPane); 
    } 

    /** 
    * Create the GUI and show it. For thread safety, 
    * this method should be invoked from the 
    * event-dispatching thread. 
    */ 
    private static void createAndShowGUI() { 
     //Create and set up the window. 
     JFrame frame = new JFrame("SimpleTableDemo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     //Create and set up the content pane. 
     SwingSolution newContentPane = new SwingSolution(); 
     newContentPane.setOpaque(true); //content panes must be opaque 
     frame.setContentPane(newContentPane); 

     //Display the window. 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     //Schedule a job for the event-dispatching thread: 
     //creating and showing this application's GUI. 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 

我嘗試過各種事情的單元格渲染和GOOGLE上搜索有關的JTable和定製的細胞,但無法弄清楚。任何幫助將不勝感激

+0

在你的數組聲明中有一個額外的逗號(雖然可能並非如此) – 2013-05-09 02:07:50

+0

感謝您的注意..現在編輯(雖然它不會給出任何錯誤或程序行爲的變化) – Mady 2013-05-09 02:11:17

+1

我有一個建議:你可以創建一個靜態表(其實很簡單),然後通過jQuery訪問其元素,例如,在我的在線測驗引擎中(鏈接到演示:http://webinfocentral.com/ )?實現的細節在我的文章中:單擊/選擇ASP.NET GridView或HTML表中的行(http://www.codeproject.com/Tips/209416/Make-the-entire-GridView-Row-clickable-and- selecta) – 2013-05-09 02:35:38

回答

5

基本上,你將有供應,你是單元格渲染器和編輯器。

在這種情況下,我將第一列值/類型更改爲int。這使我可以提供boolean以外的其他含義。

如果列值是0那麼該單元格不是「可選」,1未選中,2被選中。

我也改變了的方法isCellEditable只允許「活動」單元格是可編輯的。

enter image description here

import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.GridBagLayout; 
import java.awt.GridLayout; 
import java.awt.Insets; 
import javax.swing.JCheckBox; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.UIManager; 
import javax.swing.border.Border; 
import javax.swing.border.EmptyBorder; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.TableCellRenderer; 

public class LimitedTableCellEditor extends JPanel { 

    public LimitedTableCellEditor() { 
     super(new GridLayout(1, 0)); 

     String[] columnNames = {"", "Main Menu", "Sub Menu",}; 

     Object[][] data = { 
      {0, "File", ""}, 
      {1, "", "New"}, 
      {1, "", "Save"}, 
      {1, "", "Close"}, 
      {0, "Edit", ""}, 
      {1, "", "Delete"}, 
      {1, "", "Format"}, 
      {0, "Project", ""}, 
      {1, "", "Create New"}, 
      {1, "", "Delete"}, 
      {1, "", "Build"}, 
      {1, "", "Properties"},}; 

     DefaultTableModel model = new DefaultTableModel(data, columnNames); 
     final JTable table = new JTable(model) { 
      private static final long serialVersionUID = 1L; 

      @Override 
      public Class getColumnClass(int column) { 
       switch (column) { 
        case 0: 
         return Integer.class; 
        case 1: 
         return String.class; 
        case 2: 
         return String.class; 
        default: 
         return Boolean.class; 
       } 
      } 

      @Override 
      public boolean isCellEditable(int row, int column) { 
       boolean editable = false; 
       if (column == 0) { 
        Object value = getValueAt(row, column); 
        if (value instanceof Integer) { 
         editable = ((int)value) != 0; 
        } 
       } 
       return editable; 
      } 
     }; 

     table.getColumnModel().getColumn(0).setMaxWidth(30); 
     table.getColumnModel().getColumn(0).setCellRenderer(new ConditionalCheckBoxRenderer()); 
     table.getColumnModel().getColumn(1).setMaxWidth(100); 
     table.getColumnModel().getColumn(2).setMaxWidth(120); 

     table.setPreferredScrollableViewportSize(new Dimension(250, 195)); 
     table.setFillsViewportHeight(true); 

     //Create the scroll pane and add the table to it. 
     JScrollPane scrollPane = new JScrollPane(table); 

     //Add the scroll pane to this panel. 
     add(scrollPane); 
    } 

    /** 
    * Create the GUI and show it. For thread safety, this method should be 
    * invoked from the event-dispatching thread. 
    */ 
    private static void createAndShowGUI() { 
     //Create and set up the window. 
     JFrame frame = new JFrame("SimpleTableDemo"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     //Create and set up the content pane. 
     LimitedTableCellEditor newContentPane = new LimitedTableCellEditor(); 
     newContentPane.setOpaque(true); //content panes must be opaque 
     frame.setContentPane(newContentPane); 

     //Display the window. 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    public static class ConditionalCheckBoxRenderer extends JPanel implements TableCellRenderer { 

     private static final Border NO_FOCUS_BORDER = new EmptyBorder(1, 1, 1, 1); 
     private JCheckBox cb; 

     public ConditionalCheckBoxRenderer() { 
      setLayout(new GridBagLayout()); 
      setOpaque(false); 
      cb = new JCheckBox(); 
      cb.setOpaque(false); 
      cb.setContentAreaFilled(false); 
      cb.setMargin(new Insets(0, 0, 0, 0)); 
      add(cb); 
     } 

     @Override 
     public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { 
      setOpaque(isSelected); 
      if (isSelected) { 
       setForeground(table.getSelectionForeground()); 
       setBackground(table.getSelectionBackground()); 
      } else { 
       setForeground(table.getForeground()); 
      } 
      if (value instanceof Integer) { 
       int state = (int) value; 
       cb.setVisible(state != 0); 
       cb.setSelected(state == 2); 
      } 
      if (hasFocus) { 
       setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); 
      } else { 
       setBorder(NO_FOCUS_BORDER); 
      } 
      return this; 
     } 
    } 

    public static void main(String[] args) { 
     //Schedule a job for the event-dispatching thread: 
     //creating and showing this application's GUI. 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       createAndShowGUI(); 
      } 
     }); 
    } 
} 

我沒有做過編輯,但基本概念是一樣的...

+0

雖然UI行爲有點奇怪,但UI顯示是完美的:首先,單選框的複選框不起作用,我需要雙擊。其次,複選框顯示int值而不是選擇 – Mady 2013-05-09 02:30:19

+0

+1爲您的努力MadProgrammer – Mady 2013-05-09 02:31:39

+0

@Mandy這實際上是單元編輯器的默認行爲。你需要創建你自己的(因爲表將使用它的'int'單元格編輯器)並覆蓋'isCellEdtiable'方法來返回true;) – MadProgrammer 2013-05-09 02:34:37

2

覆蓋的getCellRenderer()方法返回一個適當的渲染器。喜歡的東西:

@Override 
public TableCellRenderer getCellRenderer(int row, int column) 
{ 
    int modelColumn = convertColumnIndexToView(column); 

    if (modelColumn == 0 && getValueAt(row, column).equals("")) 
     return getDefaultRenderer(String.class); 
    else 
     return super.getCellRenderer(row, column); 
} 

您還需要更改模型中的數據:

{"", "File", ""}, 

最後你也會重寫isCellEditable()方法,使空單元格不可編輯。

然後,您可以對列中的其他行使用默認的布爾渲染器/編輯器。

2

您可以使用Boolean包裝類代替原始類型,並編寫自己的TableCellRenderer並覆蓋getTableCellRendererComponent(..)方法。

public class CustomTableCellRenderer extends DefaultTableCellRenderer 
{ 
    public CustomTableCellRenderer() 
    { 
     super(); 
    } 

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

     if(value instanceof Boolean) 
     { 
      if(value != null) 
      { 
       JCheckBox jcb = new JCheckBox(); 
       jcb.setSelected((Boolean) value); 

       return jcb; 
      } 
      return new JPanel(); 
     } 
    return this; 
    } 
} 

然後,只需簡單地設置infos.setDefaultRenderer(Boolean.class, new CustomTableCellRenderer());new Boolean(true)替換您的原始類型在數組中。無論您何時不想擁有,您都會輸入null而不是Boolean,並且會出現空的JPanel

+0

謝謝!但最好的方法是將這與MadProgrammer的答案結合起來。 (我在CheckBox的位置上遇到了一些問題,所以我將它添加到在重寫的方法內初始化的JPanel) – nask00s 2014-07-21 12:47:25

相關問題