我正在更改由JPanel扩展的Custom类填充的JTable的LookAndFeel,但是我不能这样做。

我只编辑了我的代码,但仍然很长。

public class LAF_TableCustomContainer extends JFrame {

    public LAF_TableCustomContainer()  {
      setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      setSize(300, 300);
      setVisible(true);
      setLocationRelativeTo(null);
    }

  public static void changeLAF(Container container, String laf) {
    try {
      UIManager.setLookAndFeel(laf);
    } catch (ClassNotFoundException | InstantiationException
        | IllegalAccessException | UnsupportedLookAndFeelException e) {
    }
    SwingUtilities.updateComponentTreeUI(container);
  }

  static final JFrame frame = new JFrame();

  public JComponent makeUI() {

    String[] hdrsObjects = {"PanelSpinnerRadioButton Class Column"};
    Object[][] objectMatrix = new Object[3][1];
    objectMatrix[0][0] = new PanelSpinnerRadioButtonData(false, 10, 40);
    objectMatrix[1][0] = new PanelSpinnerRadioButtonData(true,  20, 40);
    objectMatrix[2][0] = new PanelSpinnerRadioButtonData(false, 30, 40);

    JTable table = new JTable(new DefaultTableModel(objectMatrix, hdrsObjects));
    JScrollPane scrollPane = new JScrollPane(table);
    scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
    scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    table.setRowHeight(30);

    TableColumn tc = table.getColumn("PanelSpinnerRadioButton Class Column");
    tc.setCellRenderer(new PSRBTableCellRenderer());
    tc.setCellEditor(new PSRBTableCellEditor());

    JPanel pH = new JPanel();
    pH.setLayout(new BoxLayout(pH, BoxLayout.LINE_AXIS));

    JButton bMetal = new JButton("Metal");
    bMetal.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
          changeLAF(LAF_TableCustomContainer.this, "javax.swing.plaf.metal.MetalLookAndFeel");
          changeLAF(table, "javax.swing.plaf.metal.MetalLookAndFeel");
          changeLAF(scrollPane, "javax.swing.plaf.metal.MetalLookAndFeel");
          changeLAF((JPanel)table.getModel().getValueAt(0, 0), "javax.swing.plaf.metal.MetalLookAndFeel");
      }
    });

    JButton bMotif = new JButton("Motif");
    bMotif.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
          changeLAF(LAF_TableCustomContainer.this, "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
          changeLAF(table, "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
          changeLAF(scrollPane, "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
          changeLAF((JPanel)table.getModel().getValueAt(0, 0), "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
      }
    });

    JButton bNimbus = new JButton("Nimbus");
    bNimbus.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
          changeLAF(LAF_TableCustomContainer.this, "javax.swing.plaf.nimbus.NimbusLookAndFeel");
          changeLAF(table, "javax.swing.plaf.nimbus.NimbusLookAndFeel");
          changeLAF(scrollPane, "javax.swing.plaf.nimbus.NimbusLookAndFeel");
          changeLAF((JPanel)table.getModel().getValueAt(0, 0), "javax.swing.plaf.nimbus.NimbusLookAndFeel");
      }
    });
    pH.add(bMetal);
    pH.add(bMotif);
    pH.add(bNimbus);

    JPanel pV = new JPanel();
    pV.setLayout(new BoxLayout(pV, BoxLayout.PAGE_AXIS));
    pV.add(pH);
    pV.add(scrollPane);
    return pV;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      LAF_TableCustomContainer f = new LAF_TableCustomContainer();
      f.getContentPane().add(f.makeUI());
    });
  }
}

class PanelSpinnerRadioButtonData {
  private boolean opt02 = false;
  private Integer from = 0;
  private Integer size = 1;

  PanelSpinnerRadioButtonData() {
    this(false, 5, 10);
  }
  PanelSpinnerRadioButtonData(boolean opt02, Integer from, Integer size) {
    this.opt02 = opt02;
    this.from = from;
    this.size = size;
  }
  public boolean getOption() {
    return opt02;
  }
  public Integer getFrom() {
    return from;
  }
  public Integer getSize() {
    return size;
  }
}

class PanelSpinnerRadioButton extends JPanel {
  public final JRadioButton jrbOption01 = new JRadioButton("01");
  public final JRadioButton jrbOption02 = new JRadioButton("12");
  public final JSpinner jspnValues = new JSpinner(new SpinnerNumberModel(5, 0, 10, 1));

  private final JPanel panel = new JPanel();

  PanelSpinnerRadioButton() {
    this(new PanelSpinnerRadioButtonData(false, 20, 40));
  }

  PanelSpinnerRadioButton(PanelSpinnerRadioButtonData data) {
    super();

    panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
    panel.add(jrbOption01);
    panel.add(jrbOption02);
    panel.add(Box.createRigidArea(new Dimension(5, 0)));
    panel.add(new JSeparator(JSeparator.VERTICAL));
    panel.add(Box.createRigidArea(new Dimension(5, 0)));
    panel.add(jspnValues);
    ButtonGroup bg = new ButtonGroup();
    bg.add(jrbOption01);
    bg.add(jrbOption02);
    ((SpinnerNumberModel) jspnValues.getModel()).setMaximum(data.getSize());
    setData(data);

    init();
  }

  private void init() {
    setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
    setBackground(new Color(0, 0, 0, 0));
    add(panel);
  }

  public void setData(PanelSpinnerRadioButtonData data) {
    if (data.getOption()) {
      jrbOption02.setSelected(true);
    } else {
      jrbOption01.setSelected(true);
    }
    ((SpinnerNumberModel) jspnValues.getModel()).setValue(data.getFrom());
  }

  // Used in PSRBTableCellEditor.getCellEditorValue()
  public PanelSpinnerRadioButtonData getData() {
    return new PanelSpinnerRadioButtonData(
             jrbOption02.isSelected(),
             (Integer) ((SpinnerNumberModel) jspnValues.getModel()).getValue(),
             (Integer) ((SpinnerNumberModel) jspnValues.getModel()).getMaximum());
  }
}

class PSRBTableCellRenderer implements TableCellRenderer {
  private final PanelSpinnerRadioButton renderer = new PanelSpinnerRadioButton();
  @Override public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
    if (value instanceof PanelSpinnerRadioButtonData) {
      renderer.setData((PanelSpinnerRadioButtonData) value);
    }
    return renderer;
  }
}

class PSRBTableCellEditor extends AbstractCellEditor implements TableCellEditor {
  private final PanelSpinnerRadioButton editor = new PanelSpinnerRadioButton();
  @Override public Object getCellEditorValue() {
    return editor.getData();
  }
  @Override public Component getTableCellEditorComponent(
      JTable table, Object value, boolean isSelected, int row, int column) {
    if (value instanceof PanelSpinnerRadioButtonData) {
      editor.setData((PanelSpinnerRadioButtonData) value);
    }
    return editor;
  }
}

当我按下某个按钮时,除包含自定义JPanel的JTable的单元格外,所有JFrame都会更改。

java - 更改自定义组件JTable的LookAndFeel-LMLPHP

我试图只强迫第一个牢房...
changeLAF((JPanel)table.getModel().getValueAt(0, 0), "javax.swing.plaf.metal.MetalLookAndFeel");

但我有例外:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: PanelSpinnerRadioButtonData cannot be cast to javax.swing.JPanel

最佳答案

  • SwingUtilities#updateComponentTreeUI(...)方法的局限在于单元格渲染器LookAndFeel不能更改
  • 由于PSRBTableCellRenderer不扩展JComponent,因此它不受LookAndFeel方法
  • SwingUtilities # updateComponentTreeUI (...)更新的约束

    // @see javax/swing/SwingUtilities.java
    public static void updateComponentTreeUI(Component c) {
        updateComponentTreeUI0(c);
        c.invalidate();
        c.validate();
        c.repaint();
    }
    private static void updateComponentTreeUI0(Component c) {
        if (c instanceof JComponent) {
            JComponent jc = (JComponent) c;
            jc.updateUI();
            JPopupMenu jpm =jc.getComponentPopupMenu();
            if(jpm != null) {
                updateComponentTreeUI(jpm);
            }
        }
        Component[] children = null;
        if (c instanceof JMenu) {
            children = ((JMenu)c).getMenuComponents();
        }
        else if (c instanceof Container) {
            children = ((Container)c).getComponents();
        }
        if (children != null) {
            for (Component child : children) {
                updateComponentTreeUI0(child);
            }
        }
    }
    

    您可以通过重写JTable#updateUI()方法并重新创建单元格渲染器和编辑器来避免这种情况。
    JTable table = new JTable(new DefaultTableModel(objectMatrix, hdrsObjects)) {
      @Override public void updateUI() {
        super.updateUI();
        setRowHeight(30);
        TableColumn tc = getColumn("PanelSpinnerRadioButton Class Column");
        tc.setCellRenderer(new PSRBTableCellRenderer());
        tc.setCellEditor(new PSRBTableCellEditor());
      }
    };
    

    LAF_TableCustomContainer2.java
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import javax.swing.table.*;
    
    public class LAF_TableCustomContainer2 extends JFrame {
      public LAF_TableCustomContainer2()  {
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setSize(300, 300);
        setVisible(true);
        setLocationRelativeTo(null);
      }
    
      public static void changeLAF(Container container, String laf) {
        try {
          UIManager.setLookAndFeel(laf);
        } catch (ClassNotFoundException | InstantiationException
               | IllegalAccessException | UnsupportedLookAndFeelException e) {
        }
        SwingUtilities.updateComponentTreeUI(container);
      }
    
      static final JFrame frame = new JFrame();
    
      public JComponent makeUI() {
        JPanel pV = new JPanel();
          pV.setLayout(new BoxLayout(pV, BoxLayout.PAGE_AXIS));
    
        String[] hdrsObjects = {"PanelSpinnerRadioButton Class Column"};
        Object[][] objectMatrix = new Object[3][1];
        objectMatrix[0][0] = new PanelSpinnerRadioButtonData(false, 10, 40);
        objectMatrix[1][0] = new PanelSpinnerRadioButtonData(true,  20, 40);
        objectMatrix[2][0] = new PanelSpinnerRadioButtonData(false, 30, 40);
    
          JTable table = new JTable(new DefaultTableModel(objectMatrix, hdrsObjects)) {
              @Override public void updateUI() {
                  super.updateUI();
                  setRowHeight(30);
                  TableColumn tc = getColumn("PanelSpinnerRadioButton Class Column");
                  tc.setCellRenderer(new PSRBTableCellRenderer());
                  tc.setCellEditor(new PSRBTableCellEditor());
              }
          };
        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    //     table.setRowHeight(30);
    //     TableColumn tc = table.getColumn("PanelSpinnerRadioButton Class Column");
    //     tc.setCellRenderer(new PSRBTableCellRenderer());
    //     tc.setCellEditor(new PSRBTableCellEditor());
    
        JPanel pH = new JPanel();
        pH.setLayout(new BoxLayout(pH, BoxLayout.LINE_AXIS));
    
        JButton bMetal = new JButton("Metal");
        bMetal.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            changeLAF(pV, "javax.swing.plaf.metal.MetalLookAndFeel");
          }
        });
    
        JButton bMotif = new JButton("Motif");
        bMotif.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            changeLAF(pV, "com.sun.java.swing.plaf.motif.MotifLookAndFeel");
          }
        });
    
        JButton bNimbus = new JButton("Nimbus");
        bNimbus.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
            changeLAF(pV, "javax.swing.plaf.nimbus.NimbusLookAndFeel");
          }
        });
        pH.add(bMetal);
        pH.add(bMotif);
        pH.add(bNimbus);
    
        pV.add(pH);
        pV.add(scrollPane);
        return pV;
      }
      public static void main(String... args) {
        EventQueue.invokeLater(() -> {
          LAF_TableCustomContainer2 f = new LAF_TableCustomContainer2();
          f.getContentPane().add(f.makeUI());
        });
      }
    }
    
    class PanelSpinnerRadioButtonData {
      private boolean opt02 = false;
      private Integer from = 0;
      private Integer size = 1;
    
      PanelSpinnerRadioButtonData() {
        this(false, 5, 10);
      }
      PanelSpinnerRadioButtonData(boolean opt02, Integer from, Integer size) {
        this.opt02 = opt02;
        this.from = from;
        this.size = size;
      }
      public boolean getOption() {
        return opt02;
      }
      public Integer getFrom() {
        return from;
      }
      public Integer getSize() {
        return size;
      }
    }
    
    class PanelSpinnerRadioButton extends JPanel {
      public final JRadioButton jrbOption01 = new JRadioButton("01");
      public final JRadioButton jrbOption02 = new JRadioButton("12");
      public final JSpinner jspnValues = new JSpinner(new SpinnerNumberModel(5, 0, 10, 1));
    
      private final JPanel panel = new JPanel();
    
      PanelSpinnerRadioButton() {
        this(new PanelSpinnerRadioButtonData(false, 20, 40));
      }
    
      PanelSpinnerRadioButton(PanelSpinnerRadioButtonData data) {
        super();
    
        panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
        panel.add(jrbOption01);
        panel.add(jrbOption02);
        panel.add(Box.createRigidArea(new Dimension(5, 0)));
        panel.add(new JSeparator(JSeparator.VERTICAL));
        panel.add(Box.createRigidArea(new Dimension(5, 0)));
        panel.add(jspnValues);
        ButtonGroup bg = new ButtonGroup();
        bg.add(jrbOption01);
        bg.add(jrbOption02);
        ((SpinnerNumberModel) jspnValues.getModel()).setMaximum(data.getSize());
        setData(data);
    
        init();
      }
    
      private void init() {
        setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
        setBackground(new Color(0, 0, 0, 0));
        add(panel);
      }
    
      public void setData(PanelSpinnerRadioButtonData data) {
        if (data.getOption()) {
          jrbOption02.setSelected(true);
        } else {
          jrbOption01.setSelected(true);
        }
        ((SpinnerNumberModel) jspnValues.getModel()).setValue(data.getFrom());
      }
    
      // Used in PSRBTableCellEditor.getCellEditorValue()
      public PanelSpinnerRadioButtonData getData() {
        return new PanelSpinnerRadioButtonData(
                 jrbOption02.isSelected(),
                 (Integer)((SpinnerNumberModel) jspnValues.getModel()).getValue(),
                 (Integer)((SpinnerNumberModel) jspnValues.getModel()).getMaximum());
      }
    }
    
    class PSRBTableCellRenderer implements TableCellRenderer {
      private final PanelSpinnerRadioButton renderer = new PanelSpinnerRadioButton();
      @Override public Component getTableCellRendererComponent(
        JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
        if (value instanceof PanelSpinnerRadioButtonData) {
          renderer.setData((PanelSpinnerRadioButtonData) value);
        }
        return renderer;
      }
    }
    
    class PSRBTableCellEditor extends AbstractCellEditor implements TableCellEditor {
      private final PanelSpinnerRadioButton editor = new PanelSpinnerRadioButton();
      @Override public Object getCellEditorValue() {
        return editor.getData();
      }
      @Override public Component getTableCellEditorComponent(
        JTable table, Object value, boolean isSelected, int row, int column) {
        if (value instanceof PanelSpinnerRadioButtonData) {
          editor.setData((PanelSpinnerRadioButtonData) value);
        }
        return editor;
      }
    }
    

    07-26 06:11