Memperbaiki bug Latar Belakang Warna JTextPane saat Nimbus atau GTK LookAndFeeel Digunakan, dengan metode override

Saya mencoba mengubah Warna latar belakang JTextPane, yang terkandung seperti Sel JTable dengan masalah terkait dalam pertanyaan ini JTable, perbarui Sel Warna saat LookAndFeel Nimbus atau GTK digunakan

Saya kemudian menemukan bug tersebut (dan bukan solusi yang berlaku untuk saya) 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);
    }
});

Dan jawaban ini 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);

Saya juga membutuhkan Warna Nimbus asli dan warna untuk Pilih Latar Belakang Sel JTable ...

Di sini kode lengkap dan fungsional (Memperbaiki perpustakaan impor).

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());
        }
      }
    };

  }
}

Kode untuk Perubahan Warna Sel JTable (Tidak digunakan di kelas sebelumnya, hanya untuk menunjukkan konsekuensi dari 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);
    }
  }

Saya mencoba mengulas warisan LookAndFeel untuk menemukan banyak solusi, tetapi saya tidak bisa.

//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)

Metode apa yang Anda sarankan untuk diganti (untuk mengubah Warna Latar Belakang JTextPane saat Nimbus digunakan), untuk menyelesaikannya dengan mengubah kode LookAndFeels?


person Anita    schedule 30.10.2019    source sumber