覆盖选择颜色 - Jtree
Override selection color - Jtree
DefaultTreeCellRenderer
中有一个名为 setBackgroundSelectionColor()
的方法,它允许您在 select JTree
上的项目时更改 select离子颜色.当我进入DefaultTreeCellRenderer
的源代码时,select离子颜色由getBackgroundSelectionColor()
设置在paint()
。
在下面的代码中,我试图通过简单地覆盖 paint
方法来更改 selection 颜色。问题是即使在 paint 方法中手动设置,颜色也保持不变。此外,即使 getBackgroundSelectionColor()
不再用于 paint
,方法 setBackgroundSelectionColor()
仍然有效。
为什么会这样,我怎样才能正确覆盖颜色?
不使用 setBackgroundSelectionColor()
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
@SuppressWarnings("serial")
public class DirectoryExplorer extends JFrame {
private DirectoryExplorer() {
super("Directory Explorer");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(1, 1));
createPanel();
setSize(800,600);
setVisible(true);
}
private void createPanel() {
JPanel panel = new JPanel(new GridLayout(1, 1));
JTree tree = new JTree();
paintRenderer pR = new paintRenderer();
tree.setCellRenderer(pR);
//pR.setBackgroundSelectionColor(Color.RED); //Why does this work when changing value in paint doesn't
panel.add(new JScrollPane(tree));
getContentPane().add(panel);
}
public static void main(String[] args) {
new DirectoryExplorer();
}
private class paintRenderer extends DefaultTreeCellRenderer {
@Override
public void paint(Graphics g) {
Color bColor;
if (selected) {
bColor = Color.RED;//= getBackgroundSelectionColor();
} else {
bColor = getBackgroundNonSelectionColor();
if (bColor == null) {
bColor = getBackground();
}
}
//super.paint(g); //Paints the correct colors but no text
int imageOffset = -1;
if (bColor != null) {
imageOffset = getLabelStart();
g.setColor(bColor);
if(getComponentOrientation().isLeftToRight()) {
g.fillRect(imageOffset, 0, getWidth() - imageOffset, getHeight());
} else {
g.fillRect(0, 0, getWidth() - imageOffset, getHeight());
}
}
if (hasFocus) {
if (imageOffset == -1) {
imageOffset = getLabelStart();
}
if(getComponentOrientation().isLeftToRight()) {
paintFocus(g, imageOffset, 0, getWidth() - imageOffset, getHeight(), bColor);
} else {
paintFocus(g, 0, 0, getWidth() - imageOffset, getHeight(), bColor);
}
}
super.paint(g); //Paints text but wrong colors
}
private void paintFocus(Graphics g, int x, int y, int w, int h, Color notColor) {
Color bsColor = Color.RED;//= getBorderSelectionColor();
if (bsColor != null && selected) {
g.setColor(bsColor);
g.drawRect(x, y, w - 1, h - 1);
}
}
private int getLabelStart() {
Icon currentI = getIcon();
if(currentI != null && getText() != null) {
return currentI.getIconWidth() + Math.max(0, getIconTextGap() - 1);
}
return 0;
}
}
}
编辑
目前的样子
问题是你重写了 paint(...)
而不是 paintComponent(...)
如本 answer 中所述,对于 swing 中不是顶级容器的内容,您不应覆盖 paint
,相反,您应该覆盖 paintComponent
.
将代码更改为如下所示。
@Override
public void paintComponent(Graphics g) {
...
super.paintComponent(g);
}
例如
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
@SuppressWarnings("serial")
public class DirectoryExplorer extends JFrame {
private DirectoryExplorer() {
super("Directory Explorer");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(1, 1));
createPanel();
setSize(800,600);
setVisible(true);
}
private void createPanel() {
JPanel panel = new JPanel(new GridLayout(1, 1));
JTree tree = new JTree();
paintRenderer pR = new paintRenderer();
tree.setCellRenderer(pR);
panel.add(new JScrollPane(tree));
getContentPane().add(panel);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new DirectoryExplorer());
}
private class paintRenderer extends DefaultTreeCellRenderer {
@Override
public void paintComponent(Graphics g) {
Color bColor;
if (selected) {
bColor = Color.RED;
} else {
bColor = getBackgroundNonSelectionColor();
if (bColor == null) {
bColor = getBackground();
}
}
int imageOffset = -1;
if (bColor != null) {
imageOffset = getLabelStart();
g.setColor(bColor);
if(getComponentOrientation().isLeftToRight()) {
g.fillRect(imageOffset, 0, getWidth() - imageOffset, getHeight());
} else {
g.fillRect(0, 0, getWidth() - imageOffset, getHeight());
}
}
if (hasFocus) {
if (imageOffset == -1) {
imageOffset = getLabelStart();
}
if(getComponentOrientation().isLeftToRight()) {
paintFocus(g, imageOffset, 0, getWidth() - imageOffset, getHeight());
} else {
paintFocus(g, 0, 0, getWidth() - imageOffset, getHeight());
}
}
super.paintComponent(g);
}
private void paintFocus(Graphics g, int x, int y, int w, int h) {
Color bsColor = Color.RED;
if (bsColor != null && selected) {
g.setColor(bsColor);
g.drawRect(x, y, w - 1, h - 1);
}
}
private int getLabelStart() {
Icon currentI = getIcon();
if(currentI != null && getText() != null) {
return currentI.getIconWidth() + Math.max(0, getIconTextGap() - 1);
}
return 0;
}
}
}
DefaultTreeCellRenderer
中有一个名为 setBackgroundSelectionColor()
的方法,它允许您在 select JTree
上的项目时更改 select离子颜色.当我进入DefaultTreeCellRenderer
的源代码时,select离子颜色由getBackgroundSelectionColor()
设置在paint()
。
在下面的代码中,我试图通过简单地覆盖 paint
方法来更改 selection 颜色。问题是即使在 paint 方法中手动设置,颜色也保持不变。此外,即使 getBackgroundSelectionColor()
不再用于 paint
,方法 setBackgroundSelectionColor()
仍然有效。
为什么会这样,我怎样才能正确覆盖颜色?
不使用 setBackgroundSelectionColor()
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
@SuppressWarnings("serial")
public class DirectoryExplorer extends JFrame {
private DirectoryExplorer() {
super("Directory Explorer");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(1, 1));
createPanel();
setSize(800,600);
setVisible(true);
}
private void createPanel() {
JPanel panel = new JPanel(new GridLayout(1, 1));
JTree tree = new JTree();
paintRenderer pR = new paintRenderer();
tree.setCellRenderer(pR);
//pR.setBackgroundSelectionColor(Color.RED); //Why does this work when changing value in paint doesn't
panel.add(new JScrollPane(tree));
getContentPane().add(panel);
}
public static void main(String[] args) {
new DirectoryExplorer();
}
private class paintRenderer extends DefaultTreeCellRenderer {
@Override
public void paint(Graphics g) {
Color bColor;
if (selected) {
bColor = Color.RED;//= getBackgroundSelectionColor();
} else {
bColor = getBackgroundNonSelectionColor();
if (bColor == null) {
bColor = getBackground();
}
}
//super.paint(g); //Paints the correct colors but no text
int imageOffset = -1;
if (bColor != null) {
imageOffset = getLabelStart();
g.setColor(bColor);
if(getComponentOrientation().isLeftToRight()) {
g.fillRect(imageOffset, 0, getWidth() - imageOffset, getHeight());
} else {
g.fillRect(0, 0, getWidth() - imageOffset, getHeight());
}
}
if (hasFocus) {
if (imageOffset == -1) {
imageOffset = getLabelStart();
}
if(getComponentOrientation().isLeftToRight()) {
paintFocus(g, imageOffset, 0, getWidth() - imageOffset, getHeight(), bColor);
} else {
paintFocus(g, 0, 0, getWidth() - imageOffset, getHeight(), bColor);
}
}
super.paint(g); //Paints text but wrong colors
}
private void paintFocus(Graphics g, int x, int y, int w, int h, Color notColor) {
Color bsColor = Color.RED;//= getBorderSelectionColor();
if (bsColor != null && selected) {
g.setColor(bsColor);
g.drawRect(x, y, w - 1, h - 1);
}
}
private int getLabelStart() {
Icon currentI = getIcon();
if(currentI != null && getText() != null) {
return currentI.getIconWidth() + Math.max(0, getIconTextGap() - 1);
}
return 0;
}
}
}
编辑
目前的样子
问题是你重写了 paint(...)
而不是 paintComponent(...)
如本 answer 中所述,对于 swing 中不是顶级容器的内容,您不应覆盖 paint
,相反,您应该覆盖 paintComponent
.
将代码更改为如下所示。
@Override
public void paintComponent(Graphics g) {
...
super.paintComponent(g);
}
例如
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
@SuppressWarnings("serial")
public class DirectoryExplorer extends JFrame {
private DirectoryExplorer() {
super("Directory Explorer");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new GridLayout(1, 1));
createPanel();
setSize(800,600);
setVisible(true);
}
private void createPanel() {
JPanel panel = new JPanel(new GridLayout(1, 1));
JTree tree = new JTree();
paintRenderer pR = new paintRenderer();
tree.setCellRenderer(pR);
panel.add(new JScrollPane(tree));
getContentPane().add(panel);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new DirectoryExplorer());
}
private class paintRenderer extends DefaultTreeCellRenderer {
@Override
public void paintComponent(Graphics g) {
Color bColor;
if (selected) {
bColor = Color.RED;
} else {
bColor = getBackgroundNonSelectionColor();
if (bColor == null) {
bColor = getBackground();
}
}
int imageOffset = -1;
if (bColor != null) {
imageOffset = getLabelStart();
g.setColor(bColor);
if(getComponentOrientation().isLeftToRight()) {
g.fillRect(imageOffset, 0, getWidth() - imageOffset, getHeight());
} else {
g.fillRect(0, 0, getWidth() - imageOffset, getHeight());
}
}
if (hasFocus) {
if (imageOffset == -1) {
imageOffset = getLabelStart();
}
if(getComponentOrientation().isLeftToRight()) {
paintFocus(g, imageOffset, 0, getWidth() - imageOffset, getHeight());
} else {
paintFocus(g, 0, 0, getWidth() - imageOffset, getHeight());
}
}
super.paintComponent(g);
}
private void paintFocus(Graphics g, int x, int y, int w, int h) {
Color bsColor = Color.RED;
if (bsColor != null && selected) {
g.setColor(bsColor);
g.drawRect(x, y, w - 1, h - 1);
}
}
private int getLabelStart() {
Icon currentI = getIcon();
if(currentI != null && getText() != null) {
return currentI.getIconWidth() + Math.max(0, getIconTextGap() - 1);
}
return 0;
}
}
}