【问题标题】:JTable and JColorChooser: Changes are not keptJTable 和 JColorChooser:不保留更改
【发布时间】:2018-07-01 04:43:42
【问题描述】:

我已经尝试了几天在 JTable 中编写颜色选择器,但没有成功。我尝试结合不同的教程(hereherehere)。我也尝试过使用 DefaultTableModel。

我无法在适当的时候触发颜色更改并保留它们。单击另一个按钮时,您将看到图标发生变化。我觉得我接近解决方案,但我真的被困住了。

如果有人能找出问题所在,那就太好了。

谢谢!

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;

import javax.swing.BoxLayout;
import javax.swing.DefaultCellEditor;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableCellRenderer;


public class ButtonExample extends JFrame {

private Object[][] data = {{"toto.bw", "toto", "Button"},
          {"tata.bw", "tata", "Button"},
          {"titi.bw", "titi", "Button"},
          {"tutu.bw", "tutu", "Button"}};
private String[] title = {"Bigwig", "Name", "Color"};
//private TableColumn columnColor;
private CustomTableModel customModel = new CustomTableModel(data,title);
private JTable bigwigsTab = new JTable(customModel);


public ButtonExample(){

    this.setTitle("Button Example");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocationRelativeTo(null);

    this.setExtendedState(MAXIMIZED_BOTH);
    this.setMinimumSize(new Dimension(400,400));
    this.setResizable(true);

    JScrollPane tableContainer = new JScrollPane(bigwigsTab);
    bigwigsTab.setPreferredScrollableViewportSize(new Dimension(400, 400/3));
    bigwigsTab.setFillsViewportHeight(true);
    bigwigsTab.setDefaultRenderer(JButton.class, new TableComponent());
    bigwigsTab.getColumn("Color").setCellRenderer(new ButtonRenderer(Color.blue));
    bigwigsTab.getColumn("Color").setCellEditor(new ButtonEditor(new JCheckBox()));

    this.setBackground(Color.white);
    this.add(tableContainer);
    this.setVisible(true);
}

 public class CustomTableModel extends AbstractTableModel {

     private Object[][] data;
     private String[] title;

     public CustomTableModel(Object[][] data, String[] title) {

         this.data = data;
         this.title = title;
    }

     public int getColumnCount(){
         return this.title.length;
     }

     public int getRowCount(){
         return this.data.length;
     }

     public Object getValueAt(int row, int col){
         return this.data[row][col];
     }

     public String getColumnName(int col){
         return this.title[col];
     }

     public Class getColumnClass(int col){
         return this.data[0][col].getClass();
     }

     public boolean isCellEditable(int row, int col){
         if(col==0 || col ==3) return false; //bigwig name and color button should not be editable
         return true;
     }

     public void setValueAt(Object value, int row, int col){

         this.data[row][col] = value;
     }
}


 public class TableComponent extends DefaultTableCellRenderer{

     public Component getTableCellRendererComponent(JTable table, Object value, 
             boolean isSelected, boolean hasFocus, int row, int column){

         if(value instanceof JButton)
             return (JButton) value;
         else
             return this;
     }
 }


 public class ButtonRenderer extends JButton implements TableCellRenderer{

     private Color currentColor;

     public ButtonRenderer(Color c){
         this.currentColor = c;
         this.setSelectedColor(currentColor);
     }

     public Component getTableCellRendererComponent(JTable table, Object value, 
             boolean isSelected, boolean isFocus, int row, int col){
         setText((value != null) ? value.toString():"");

         return this;
     }

     private void setSelectedColor(Color newColor) {
         if (newColor == null) return;

         currentColor = newColor;
         this.setIcon(createIcon(currentColor, 16, 16));
         this.repaint();
     }

     private ImageIcon createIcon(Color main, int width, int height) {
         BufferedImage image = new BufferedImage(width, height, java.awt.image.BufferedImage.TYPE_INT_RGB);
         Graphics2D graphics = image.createGraphics();
         graphics.setColor(main);
         graphics.fillRect(0, 0, width, height);
         graphics.setXORMode(Color.DARK_GRAY);
         graphics.drawRect(0, 0, width-1, height-1);
         image.flush();
         ImageIcon icon = new ImageIcon(image);
         return icon;
     }
 }


 public class ButtonEditor extends DefaultCellEditor{

     protected JButton button;
     private boolean isPushed;
     private ButtonListener bListener = new ButtonListener();
     private Color selectedColor = null;


     public ButtonEditor(JCheckBox checkBox){
         super(checkBox);
         button = new JButton();
         button.setOpaque(true);
         button.addActionListener(bListener);
     }

     public Component getTableCellEditorComponent(JTable table, Object value,
             boolean isSelected, int row, int column){
         bListener.setRow(row);
         bListener.setColumn(column);
         bListener.setTable(table);
         button.setText((value == null) ? "":value.toString());
         return button;
     }

     class ButtonListener implements ActionListener{

         private int column, row;
         private JTable table;
         private int nbre = 0;
         private JButton button;

         public void setColumn(int col){this.column = col;}
         public void setRow(int row){this.row = row;}
         public void setTable(JTable table){this.table = table;}

         public JButton getButton(){return this.button;}

         public void actionPerformed(ActionEvent event){
             Color newColor = JColorChooser.showDialog(null, "Choose a color", Color.blue);
             setSelectedColor();
             ((AbstractTableModel)table.getModel()).setValueAt(button, this.row, this.column);
             ((AbstractTableModel)table.getModel()).fireTableCellUpdated(this.row, this.column);
             selectedColor = newColor;
             this.button = ((JButton)event.getSource());
         }
     }

     private void setSelectedColor() {
         if (selectedColor == null) return;

         button.setIcon(createIcon(selectedColor, 16, 16));
         button.repaint();
     }

     private ImageIcon createIcon(Color main, int width, int height) {
         BufferedImage image = new BufferedImage(width, height, java.awt.image.BufferedImage.TYPE_INT_RGB);
         Graphics2D graphics = image.createGraphics();
         graphics.setColor(main);
         graphics.fillRect(0, 0, width, height);
         graphics.setXORMode(Color.DARK_GRAY);
         graphics.drawRect(0, 0, width-1, height-1);
         image.flush();
         ImageIcon icon = new ImageIcon(image);
         return icon;
     }
 }

 public static void main(String[] args) {

        ButtonExample coreFacility = new ButtonExample();
        coreFacility.setVisible(true);
    }

 }

【问题讨论】:

  • Using Other Editors 上的 Swing 教程中的工作示例开始,它展示了如何使用颜色选择器来更改单元格的背景。

标签: java swing jtable jcolorchooser


【解决方案1】:

抱歉,您的代码示例很难找到错误。所以我决定写我自己的,这样你就可以有一些想法。这是我对上述给定任务的方法。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;

class ColorTableModel extends AbstractTableModel {

    Object rowData[][] = {{"Name 1", Color.RED}, {"Name 2", Color.BLUE}, {"Name 3", Color.GREEN}};

    String columnNames[] = {"Name", "Color"};

    public int getColumnCount() {
        return columnNames.length;
    }

    public String getColumnName(int column) {
        return columnNames[column];
    }

    public int getRowCount() {
        return rowData.length;
    }

    public Object getValueAt(int row, int column) {
        return rowData[row][column];
    }

    public Class getColumnClass(int column) {
        return this.rowData[0][column].getClass();
    }

    public void setValueAt(Object value, int row, int column) {
        rowData[row][column] = value;
    }

    public boolean isCellEditable(int row, int column) {
        return (column != 0);
    }
}

class ColorChooserEditor extends AbstractCellEditor implements TableCellEditor {

    private JButton button = new JButton();

    Color savedColor;

    public ColorChooserEditor() {
        ActionListener actionListener = new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                Color color = JColorChooser.showDialog(button, "Choose a color", savedColor);
                ColorChooserEditor.this.changeColor(color);
            }
        };
        button.addActionListener(actionListener);
    }

    public Color getCellEditorValue() {
        return savedColor;
    }

    private void changeColor(Color color) {
        if (color != null) {
            savedColor = color;
            button.setBackground(color);
        }
    }

    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected,
            int row, int column) {
        changeColor((Color) value);
        return button;
    }

}

class ChooserTableSample {

    public static void main(String args[]) {
        JFrame frame = new JFrame("Button Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        TableModel model = new ColorTableModel();
        JTable table = new JTable(model);

        TableColumn column = table.getColumnModel().getColumn(1);

        TableCellEditor editor = new ColorChooserEditor();
        column.setCellRenderer(new ButtonRenderer());
        column.setCellEditor(editor);
        JScrollPane scrollPane = new JScrollPane(table);
        frame.add(scrollPane, BorderLayout.CENTER);
        frame.setSize(400, 150);
        frame.setVisible(true);
    }
}

class ButtonRenderer extends JButton implements TableCellRenderer {

    public Component getTableCellRendererComponent(JTable table, Object value,
            boolean isSelected, boolean isFocus, int row, int col) {
        setBackground((Color) value);

        return this;
    }

希望这对你有所帮助。

【讨论】:

  • So I decided to write my own - 为什么? Swing 教程有一个工作示例,并解释了代码的作用。当您可以阅读教程时,为什么要重新发明轮子?以身作则。
  • 非常感谢!我设法在我的软件中使用了您的代码。 @camickr我尝试了本教程,但不知何故未能将其集成到我的软件中...现在我正在尝试调整读取文件的行数,但是向量的使用会弄乱显示...如果没有经验,请使用JTable 很棘手。
猜你喜欢
  • 2012-02-15
  • 2012-03-18
  • 1970-01-01
  • 1970-01-01
  • 2020-08-28
  • 2014-07-09
  • 2021-09-08
  • 1970-01-01
  • 2014-12-05
相关资源
最近更新 更多