Swing ListCellRenderer 中的背景颜色错误

发布于 2024-08-31 20:36:33 字数 3197 浏览 8 评论 0原文

我目前正在尝试为 JList 编写自定义 ListCellRenderer。不幸的是,几乎所有示例都简单地使用 DefaultListCellRenderer 作为 JLabel 并用它完成;然而,我需要一个 JPanel(因为我需要显示更多的信息,而不仅仅是一个图标和一行文本)。

现在我对背景颜色有疑问,特别是 Nimbus PLAF。看起来我从 list.getBackground() 获得的背景颜色是白色,但绘制为灰色(或蓝灰色)。输出我得到的颜色会产生以下结果:

背景颜色:DerivedColor(color=255,255,255parent=nimbusLightBackground offsets=0.0,0.0,0.0,0 pColor=255,255,255

但是,可以看出,这不是绘制的内容。

替代文字

显然它对于所选项目效果很好。目前,我什至将单元格渲染器返回的每个组件放入 JPanel 中,设置为不透明并具有正确的前景色和背景色,但无济于事。

你知道我在这里做错了什么吗?

预计到达时间:有望运行的示例代码。

public class ParameterListCellRenderer implements ListCellRenderer {
  @Override
  public Component getListCellRendererComponent(JList list, Object value,
      int index, boolean isSelected, boolean cellHasFocus) {
    // some values we need
    Border border = null;
    Color foreground, background;
    if (isSelected) {
      background = list.getSelectionBackground();
      foreground = list.getSelectionForeground();
    } else {
      background = list.getBackground();
      foreground = list.getForeground();
    }
    if (cellHasFocus) {
      if (isSelected) {
        border = UIManager.getBorder("List.focusSelectedCellHighlightBorder");
      }
      if (border == null) {
        border = UIManager.getBorder("List.focusCellHighlightBorder");
      }
    } else {
      border = UIManager.getBorder("List.cellNoFocusBorder");
    }

    System.out.println("Background color: " + background.toString());

    JPanel outerPanel = new JPanel(new BorderLayout());
    setProperties(outerPanel, foreground, background);
    outerPanel.setBorder(border);

    JLabel nameLabel = new JLabel("Factory name here");
    setProperties(nameLabel, foreground, background);
    outerPanel.add(nameLabel, BorderLayout.PAGE_START);

    Box innerPanel = new Box(BoxLayout.PAGE_AXIS);
    setProperties(innerPanel, foreground, background);
    innerPanel.setAlignmentX(Box.LEFT_ALIGNMENT);
    innerPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));

    JLabel label = new JLabel("param: value");

    label.setFont(label.getFont().deriveFont(
        AffineTransform.getScaleInstance(0.95, 0.95)));
    setProperties(label, foreground, background);

    innerPanel.add(label);

    outerPanel.add(innerPanel, BorderLayout.CENTER);

    return outerPanel;
  }

  private void setProperties(JComponent component, Color foreground,
      Color background) {
    component.setOpaque(true);
    component.setForeground(foreground);
    component.setBackground(background);
  }
}

奇怪的是,如果我

if (isSelected) {
  background = new Color(list.getSelectionBackground().getRGB());
  foreground = new Color(list.getSelectionForeground().getRGB());
} else {
  background = new Color(list.getBackground().getRGB());
  foreground = new Color(list.getForeground().getRGB());
}

这样做,它就会神奇地起作用。那么,我到达那里的带有 nimbusLightBackgroundDerivedColor 可能会遇到麻烦吗?

I'm currently trying to write a custom ListCellRenderer for a JList. Unfortunately, nearly all examples simply use DefaultListCellRenderer as a JLabel and be done with it; I needed a JPanel, however (since I need to display a little more info than just an icon and one line of text).

Now I have a problem with the background colors, specifically with the Nimbus PLAF. Seemingly the background color I get from list.getBackground() is white, but paints as a shade of gray (or blueish gray). Outputting the color I get yields the following:

Background color: DerivedColor(color=255,255,255 parent=nimbusLightBackground offsets=0.0,0.0,0.0,0 pColor=255,255,255

However, as can be seen, this isn't what gets painted.

alt text

It obviously works fine for the selected item. Currently I even have every component I put into the JPanel the cell renderer returns set to opaque and with the correct foreground and background colors—to no avail.

Any ideas what I'm doing wrong here?

ETA: Example code which hopefully runs.

public class ParameterListCellRenderer implements ListCellRenderer {
  @Override
  public Component getListCellRendererComponent(JList list, Object value,
      int index, boolean isSelected, boolean cellHasFocus) {
    // some values we need
    Border border = null;
    Color foreground, background;
    if (isSelected) {
      background = list.getSelectionBackground();
      foreground = list.getSelectionForeground();
    } else {
      background = list.getBackground();
      foreground = list.getForeground();
    }
    if (cellHasFocus) {
      if (isSelected) {
        border = UIManager.getBorder("List.focusSelectedCellHighlightBorder");
      }
      if (border == null) {
        border = UIManager.getBorder("List.focusCellHighlightBorder");
      }
    } else {
      border = UIManager.getBorder("List.cellNoFocusBorder");
    }

    System.out.println("Background color: " + background.toString());

    JPanel outerPanel = new JPanel(new BorderLayout());
    setProperties(outerPanel, foreground, background);
    outerPanel.setBorder(border);

    JLabel nameLabel = new JLabel("Factory name here");
    setProperties(nameLabel, foreground, background);
    outerPanel.add(nameLabel, BorderLayout.PAGE_START);

    Box innerPanel = new Box(BoxLayout.PAGE_AXIS);
    setProperties(innerPanel, foreground, background);
    innerPanel.setAlignmentX(Box.LEFT_ALIGNMENT);
    innerPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));

    JLabel label = new JLabel("param: value");

    label.setFont(label.getFont().deriveFont(
        AffineTransform.getScaleInstance(0.95, 0.95)));
    setProperties(label, foreground, background);

    innerPanel.add(label);

    outerPanel.add(innerPanel, BorderLayout.CENTER);

    return outerPanel;
  }

  private void setProperties(JComponent component, Color foreground,
      Color background) {
    component.setOpaque(true);
    component.setForeground(foreground);
    component.setBackground(background);
  }
}

The weird thing is, if I do

if (isSelected) {
  background = new Color(list.getSelectionBackground().getRGB());
  foreground = new Color(list.getSelectionForeground().getRGB());
} else {
  background = new Color(list.getBackground().getRGB());
  foreground = new Color(list.getForeground().getRGB());
}

it magically works. So maybe the DerivedColor with nimbusLightBackground I'm getting there may have trouble?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

错々过的事 2024-09-07 20:36:33

JPanel 默认为 opaque=true,而 jLabels 默认为 opaque=false。

因此,当 DefaultCellRender 使用 JLabel 时,它会获取其父级的背景。

尝试在面板上将 opaque 设置为 false。

更新:

Nimbus 正在使用自己的自定义 ListCellRenderer。我发现有两次提到解决这个问题,一次在此处,一次在Google 的代码存储库(查找 UpdateUI 和 NimbusCellRenderer)。

JPanels default to opaque=true while jLabels default to opaque=false.

So, when a DefaultCellRender uses a JLabel, it gets the background of its parent.

Try just setting opaque to false on your panel.

Update:

Nimbus is using its own custom ListCellRenderer. I've found 2 mentions of working around it, one here on SO and one in Google's code repository (look for UpdateUI and NimbusCellRenderer).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文