我已經為 JComboBoxes 撰寫了一個渲染器,以便在禁用狀態時用更清晰的顏色替換乳白色。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.*;
public class RendererDemo extends JFrame {
public static final long serialVersionUID = 100L;
String[] items= {"one", "two", "three"};
public RendererDemo() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300, 100);
JComboBox<Object> cmb = new JComboBox<>(items);
// JComboBox<String> cmb = new JComboBox<>(items);
cmb.setRenderer(new DisabledDarkTextRenderer(cmb));
add(cmb, BorderLayout.NORTH);
JCheckBox check = new JCheckBox("Combo enabled", true);
add(check, BorderLayout.SOUTH);
check.addActionListener(e -> cmb.setEnabled(check.isSelected()));
setVisible(true);
}
static public void main(String args[]) {
EventQueue.invokeLater(RendererDemo::new);
}
class DisabledDarkTextRenderer extends DefaultListCellRenderer {
public static final long serialVersionUID = 50378L;
JComboBox<Object> cmb;
ListCellRenderer<Object> origRenderer;
Object defaultResource= UIManager.get("ComboBox.disabledForeground");
public DisabledDarkTextRenderer(JComboBox<Object> cmb) {
this.cmb= cmb;
origRenderer= cmb.getRenderer();
}
public Component getListCellRendererComponent(JList<?> list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
Component orig= origRenderer.getListCellRendererComponent(list, value,
index, isSelected, cellHasFocus);
if (cmb.isEnabled())
UIManager.put("ComboBox.disabledForeground", defaultResource);
else
UIManager.put("ComboBox.disabledForeground", new ColorUIResource
(Color.GRAY));
return orig;
}
}
}
但是,當我將 JComboBox 宣告為 <String> 型別時,代碼無法編譯,原因是"incompatible types: ListCellRenderer<CAP#1> cannot be converted to ListCellRenderer<Object> ..."
所以我試圖讓渲染器更通用。在我修改泛型型別的所有嘗試中,以下版本是只剩下一個錯誤的版本。這又是上面提到的錯誤,只是它現在讀取:"incompatible types: JList<CAP#1> cannot be converted to JList<? extends CAP#2> ...".
如何解決這個問題?
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.plaf.*;
public class RendererDemo2 extends JFrame {
public static final long serialVersionUID = 100L;
String[] items= {"one", "two", "three"};
public RendererDemo2() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300, 100);
JComboBox<String> cmb = new JComboBox<>(items);
cmb.setRenderer(new DisabledDarkTextRenderer2(cmb));
add(cmb, BorderLayout.NORTH);
JCheckBox check = new JCheckBox("Combo enabled", true);
add(check, BorderLayout.SOUTH);
check.addActionListener(e -> cmb.setEnabled(check.isSelected()));
setVisible(true);
}
static public void main(String args[]) {
EventQueue.invokeLater(RendererDemo2::new);
}
class DisabledDarkTextRenderer2 extends DefaultListCellRenderer {
public static final long serialVersionUID = 50379L;
JComboBox<?> cmb;
ListCellRenderer<?> origRenderer;
Object defaultResource= UIManager.get("ComboBox.disabledForeground");
public DisabledDarkTextRenderer2(JComboBox<?> cmb) {
this.cmb= cmb;
origRenderer= cmb.getRenderer();
}
public Component getListCellRendererComponent(JList<?> list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
Component orig= origRenderer.getListCellRendererComponent(list, value,
index, isSelected, cellHasFocus);
if (cmb.isEnabled())
UIManager.put("ComboBox.disabledForeground", defaultResource);
else
UIManager.put("ComboBox.disabledForeground", new ColorUIResource
(Color.GRAY));
return orig;
}
}
}
按照 MadProgrammer 的建議,我的渲染器現在看起來像這樣:
class DisabledDarkTextRenderer2<T> extends DefaultListCellRenderer {
public static final long serialVersionUID = 50379L;
JComboBox<T> cmb;
ListCellRenderer<?> origRenderer;
Object defaultResource= UIManager.get("ComboBox.disabledForeground");
public DisabledDarkTextRenderer2(JComboBox<T> cmb) {
this.cmb= cmb;
origRenderer= cmb.getRenderer();
}
public Component getListCellRendererComponent(JList<?> list, Object value,
int index, boolean isSelected, boolean cellHasFocus) {
Component orig= origRenderer.getListCellRendererComponent(list, value,
index, isSelected, cellHasFocus);
if (cmb.isEnabled())
UIManager.put("ComboBox.disabledForeground", defaultResource);
else
UIManager.put("ComboBox.disabledForeground", new ColorUIResource
(Color.GRAY));
return orig;
}
}
但編譯時錯誤仍然存??在。
我正在將此渲染器用于在運行時更改其狀態的組合。因此,我無需在每個程式中都在需要時設定顏色,因為渲染器會自動為我執行此操作。
uj5u.com熱心網友回復:
例如,您需要“通用化”您DisabledDarkTextRenderer2的 .
class DisabledDarkTextRenderer2<T> implements ListCellRenderer<T> {
public static final long serialVersionUID = 50379L;
private JComboBox<T> combobox;
private ListCellRenderer<? super T> origRenderer;
public DisabledDarkTextRenderer2(JComboBox<T> combobox) {
this.combobox = combobox;
this.origRenderer = combobox.getRenderer();
}
public static <T> void install(JComboBox<T> combobox) {
combobox.setRenderer(new DisabledDarkTextRenderer2<T>(combobox));
}
@Override
public Component getListCellRendererComponent(JList<? extends T> list, T value, int index, boolean isSelected, boolean cellHasFocus) {
Component orig = origRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (combobox.isEnabled()) {
orig.setForeground(null);
} else {
orig.setForeground(Color.GRAY);
}
return orig;
}
}
現在,話雖如此,我不鼓勵您UIManager在渲染器中使用,因為這會影響更改后渲染的所有組件,這可能是也可能不是您想要的目標,如果是這樣,那么只需在開始時設定值應用。
以下示例將為所有組合框設定默認禁用的前景色RED,而無需您執行任何其他操作。
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.ColorUIResource;
public final class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
UIManager.put("ComboBox.disabledForeground", new ColorUIResource(Color.RED));
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
setBorder(new EmptyBorder(32, 32, 32, 32));
JComboBox<String> cmb = new JComboBox<>(new String[]{"Hello", "Goodbye"});
cmb.setSelectedIndex(0);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
add(cmb, gbc);
JButton toggle = new JButton("Toggle");
toggle.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
cmb.setEnabled(!cmb.isEnabled());
}
});
add(toggle, gbc);
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/494520.html
