问题
I was trying to change background Color of JTextPane, contained like a Cell of JTable with problems related in this question JTable, update Colors Cell when LookAndFeel Nimbus or GTK are used
I discovered later the bug (and not for me applicable solution) https://bugs.openjdk.java.net/browse/JDK-8058704?jql=order%20by%20lastViewed%20DESC
UIManager.put("TextPane[Enabled].backgroundPainter", new Painter<JComponent>() {
@Override
public void paint(Graphics2D g, JComponent comp, int width, int height) {
g.setColor(comp.getBackground());
g.fillRect(0, 0, width, height);
}
});
And this answer https://stackoverflow.com/a/22674770/1410223
JEditorPane area = new JEditorPane();
Color bgColor = Color.BLACK;
UIDefaults defaults = new UIDefaults();
defaults.put("EditorPane[Enabled].backgroundPainter", bgColor);
area.putClientProperty("Nimbus.Overrides", defaults);
area.putClientProperty("Nimbus.Overrides.InheritDefaults", true);
area.setBackground(bgColor);
I need too the original Color of Nimbus and, the color for Select Background of Cell of JTable
...
Here complete and functional code (Fixing imports libraries).
public class JTextPaneSynthTest extends JFrame {
public JTextPaneSynthTest() {
JTextPane textPane = new JTextPane();
textPane.setText("something");
MetalLookAndFeel metalLAF = new MetalLookAndFeel(); //BasicTextPaneUI
MotifLookAndFeel motifLAF = new MotifLookAndFeel(); //MotifTextPaneUI
NimbusLookAndFeel nimbusLAF = new NimbusLookAndFeel(); //NimbusLookAndFeel extends SynthLookAndFeel
SynthLookAndFeel synthLAF = new SynthLookAndFeel(); //SynthTextPaneUI // SynthLookAndFeel extends BasicLookAndFeel
BasicTextPaneUI basicTextPaneUI = new BasicTextPaneUI(); // BasicTextPaneUI extends BasicEditorPaneUI
MotifTextPaneUI motifTextPaneUI = new MotifTextPaneUI(); // MotifTextPaneUI extends BasicTextPaneUI
SynthTextPaneUI synthTextPaneUI = new SynthTextPaneUI(); // SynthTextPaneUI extends SynthEditorPaneUI (SynthEditorPaneUI extends BasicEditorPaneUI implements SynthUI)
String laf = UIManager.getLookAndFeel().getName();
System.out.println("laf:" + laf);
if (laf.contains("Nimbus") || laf.contains("GTK+")) {
textPane.setUI(getSynthTextPaneUI());
textPane.revalidate();
}
TextUI textUI = textPane.getUI();
System.out.println("textUI.getClass():" + textUI.getClass());
JButton button = new JButton("Change Color");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
textPane.setBackground(Color.green);
textPane.setForeground(Color.red);
textPane.repaint();
}
});
JPanel lower = new JPanel();
lower.setLayout(new BoxLayout(lower, BoxLayout.X_AXIS));
lower.add(button);
lower.add(textPane);
JPanel main = new JPanel();
main.setLayout(new BoxLayout(main, BoxLayout.Y_AXIS));
main.add(lower);
this.add(main);
this.setSize(800, 600);
this.setVisible(true);
}
public static void main(String[] args) {
try {
/*
javax.swing.UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
javax.swing.UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");
javax.swing.UIManager.setLookAndFeel("com.apple.laf.AquaLookAndFeel");
javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
javax.swing.UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel");
*/
javax.swing.UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel");
} catch (Exception ex) {
ex.printStackTrace();
}
new JTextPaneSynthTest();
}
private static SynthTextPaneUI getSynthTextPaneUI() {
return new SynthTextPaneUI() {
@Override
public void installUI(JComponent c) {
super.installUI(c);
updateBackground(c.getBackground());
updateForeground(c.getForeground());
updateFont(c.getFont());
}
private void updateBackground(Color color) {
StyledDocument doc = (StyledDocument) getComponent().getDocument();
//doc.setCharacterAttributes(0, doc.getLength(), s, true);
Style style = doc.getStyle(StyleContext.DEFAULT_STYLE);
if (style == null) {
return;
}
if (color == null) {
style.removeAttribute(StyleConstants.Background);
} else {
StyleConstants.setBackground(style, color);
}
}
private void updateForeground(Color color) {
StyledDocument doc = (StyledDocument) getComponent().getDocument();
Style style = doc.getStyle(StyleContext.DEFAULT_STYLE);
if (style == null) {
return;
}
if (color == null) {
style.removeAttribute(StyleConstants.Foreground);
} else {
StyleConstants.setForeground(style, color);
}
}
private void updateFont(Font font) {
StyledDocument doc = (StyledDocument) getComponent().getDocument();
Style style = doc.getStyle(StyleContext.DEFAULT_STYLE);
if (style == null) {
return;
}
if (font == null) {
style.removeAttribute(StyleConstants.FontFamily);
style.removeAttribute(StyleConstants.FontSize);
style.removeAttribute(StyleConstants.Bold);
style.removeAttribute(StyleConstants.Italic);
} else {
StyleConstants.setFontFamily(style, font.getName());
StyleConstants.setFontSize(style, font.getSize());
StyleConstants.setBold(style, font.isBold());
StyleConstants.setItalic(style, font.isItalic());
}
}
};
}
}
The code for JTable Cells Color changing (It is not used in the before class, only to show the consequences of the Bug)
private class CellRenderer extends DefaultTableCellRenderer implements TableCellRenderer {
private final Panel panel = new Panel(); // This class contains a JTextPane, named textPane
//javax.swing.table.TableCellRenderer
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
if (value instanceof Info) {
panel.setData((Info) value);
String laf = UIManager.getLookAndFeel().getName().toLowerCase();
Color background;
Color foreground;
if (laf.contains("nimbus")) {
NimbusLookAndFeel nimbusLAF = new NimbusLookAndFeel();
if (isSelected) {
background = (nimbusLAF.getDerivedColor("nimbusSelectionBackground", 0.0f, 0.0f, 0.0f, 0, false));
foreground = (nimbusLAF.getDerivedColor("nimbusLightBackground", 0.0f, 0.0f, 0.0f, 0, false));
} else {
if (row % 2 == 0) {
background = nimbusLAF.getDerivedColor("Table.background", 0.0f, 0.0f, 0.0f, 0, false);
} else {
background = nimbusLAF.getDerivedColor("Table.alternateRowColor", 0.0f, 0.0f, 0.0f, 0, false);
}
foreground = nimbusLAF.getDerivedColor("Table.foreground", 0.0f, 0.0f, 0.0f, 0, false);
}
} else {
if (isSelected) {
background = (Color) UIManager.get("Table.selectionBackground");
foreground = (Color) UIManager.get("Table.selectionForeground");
} else {
background = (Color) UIManager.get("Table.background");
foreground = (Color) UIManager.get("Table.foreground");
}
}
// In order to fix the problem with GTK LookAndFeel
background = new Color(background.getRed(), background.getGreen(), background.getBlue());
foreground = new Color(foreground.getRed(), foreground.getGreen(), foreground.getBlue());
panel.getTextPane().setBackground(background);
panel.getTextPane().setForeground(foreground);
return panel;
}
return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
}
}
I was trying to review, the heritance of LookAndFeel's in order to discover a plenty solution, but I could not.
//http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/macosx/classes/com/apple/laf/AquaLookAndFeel.java
//AquaLookAndFeel aquaLAF = new AquaLookAndFeel(); //AquaTextPaneUI // AquaLookAndFeel extends BasicLookAndFeel
//http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/macosx/classes/com/apple/laf/AquaTextPaneUI.java
//AquaTextPaneUI aquaTextPaneUI = new AquaTextPaneUI(); // AquaTextPaneUI extends BasicTextPaneUI
//http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java
//GTKLookAndFeel gtkLAF = new GTKLookAndFeel(); //SynthTextPaneUI // GTKLookAndFeel extends SynthLookAndFeel
//http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java
//WindowsLookAndFeel windowsLAF = new WindowsLookAndFeel(); //WindowsTextPaneUI // WindowsLookAndFeel extends BasicLookAndFeel
//http://hg.openjdk.java.net/jdk8/jdk8/jdk/file/687fd7c7986d/src/share/classes/com/sun/java/swing/plaf/windows/WindowsTextPaneUI.java
//WindowsTextPaneUI windowsTextPaneUI = new WindowsTextPaneUI(); //WindowsTextPaneUI extends BasicTextPaneUI (BasicTextPaneUI extends BasicEditorPaneUI)
What methods do you suggest to override (to change Background Color of JTextPane
when Nimbus
is used), in order to solve it by changing the LookAndFeels code?
来源:https://stackoverflow.com/questions/58618209/fixing-background-bug-color-of-jtextpane-when-nimbus-or-gtk-lookandfeeel-is-used