[英]JTextField doesn't show when the Paint method is overridden
我正在用Java语言编写一个简单的颜色选择器,并添加了一些JTextFields
以获取用户输入。 我将文本字段添加到JPanel
,但是由于某些原因,当我覆盖paint方法时,它们不会出现。 但是,当我在不覆盖paint方法的情况下运行该程序时,将显示文本字段。 我知道它们的存在,因为当我将鼠标悬停在它们上方时,光标会发生变化,并且如果添加工具提示文本,它也会显示出来。 如何显示文本字段? 这是代码:
public class ColorSlider extends JPanel {
private ColorChooser parent;
private int sliderX = 0;
private JTextField textField = new JTextField();
public ColorSlider(ColorChooser parent, int x, int y, String toolTip) {
this.parent = parent;
parent.add(this);
setBounds(x, y, 96, 16);
setVisible(true);
setOpaque(false);
setFocusable(true);
addMouseListener(this);
addMouseMotionListener(this);
setToolTipText(toolTip);
setLayout(null);
textField.setBounds(80, 0, 16, 16); // Yes, I know this is way too small
textField.setText("Text");
add(textField);
}
@Override
public void paint(Graphics g) {
g.setColor(new Color(0xDDDDE1));
g.fillRect(0, 4, 80, 8);
g.setColor(new Color(0x444448));
g.fillRect(sliderX, 0, 8, 16);
}
首先看一下在AWT和Swing中 执行自定义绘画和绘画
从本质上讲,您所做的就是打破油漆链。 绘画是由一系列链接的方法调用组成的,每种方法都会在过程,背景,边框,子项等中添加一些内容。
通过重写paint
并无法调用super.paint
,可以防止面板为子级绘画。
现在,您可以改写paintComponent
(确保您调用super.paintComponent
),仍然会super.paintComponent
问题,因为绘制是在子组件后面完成的。
更好(更简单)的解决方案是创建两个JPanel
并在那里使用background
颜色属性以根据需要简单地更改颜色。
不要使用null
布局,像素完美布局是现代GUI设计中的一种错觉,您无法控制渲染在不同平台上的工作方式,尤其是字体的渲染方式。
利用适当的布局管理器
额外...
分开负责的领域。 “滑块”负责...的滑动。 创建一个仅提供该功能的组件。 然后创建另一个组件,该组件使用此滑块和JTextField
引入扩展功能...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class ColorSliderTest {
public static void main(String[] args) {
new ColorSliderTest();
}
public ColorSliderTest() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ColorSliderPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class ColorSliderPane extends JPanel {
private final ColorSliderControl colorSliderControl;
private final JTextField field;
public ColorSliderPane() {
field = new JTextField(5);
colorSliderControl = new ColorSliderControl();
setLayout(new BorderLayout());
add(colorSliderControl);
JPanel filler = new JPanel();
filler.add(field);
add(filler, BorderLayout.SOUTH);
}
}
public class ColorSliderControl extends JPanel {
private int sliderX;
public ColorSliderControl() {
setOpaque(false);
setBorder(new EmptyBorder(4, 4, 4, 4));
}
@Override
public Dimension getPreferredSize() {
Insets insets = getInsets();
int width = 80 + (insets.left + insets.right);
int height = 16 + (insets.top + insets.bottom);
return new Dimension(width, height);
}
@Override
public void paint(Graphics g) {
Insets insets = getInsets();
int y = getHeight() / 2;
int x = insets.left;
int width = getWidth() - (insets.left + insets.right);
g.setColor(new Color(0xDDDDE1));
g.fillRect(x, y - 4, width, 8);
g.setColor(new Color(0x444448));
g.fillRect(sliderX + x, y - 8, 8, 16);
}
}
}
在您说“但我希望字段在右边”之前,请先更改
add(filler, BorderLayout.SOUTH);
至
add(filler, BorderLayout.EAST);
我可能还会提到JSlider
我想你已经画了他们。
这是一种处理UI代码的绝妙方法。 您要通过在面板的硬编码位置上放置两个具有硬编码颜色的矩形来实现什么目的?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.