JTextField不会显示何时覆盖Paint方法

时间:2014-03-20 23:32:48

标签: java swing paint jtextfield

我在java中编写了一个简单的颜色选择器,并添加了一些JTextFields来获取用户输入。我将文本字段添加到JPanel,但出于某种原因,当我覆盖绘制方法时,它们不会出现。但是,当我在不重写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);
    }

2 个答案:

答案 0 :(得分:3)

首先看看Performing Custom PaintingPainting in AWT and Swing

基本上你所做的就是破坏油漆链。绘画由一系列链式方法调用组成,每个方法都为进程,背景,边框,子代等添加内容。

通过覆盖paint并且无法调用super.paint,您已阻止小组为其绘制子项。

现在,您可以覆盖paintComponent(确保您调用super.paintComponent),您仍然可能会遇到问题,因为绘画是在子组件后面完成的。

更好(更简单)的解决方案是创建两个JPanel并使用background颜色属性来根据需要更改颜色。

不要使用null布局,像素完美布局在现代GUI设计中是一种幻觉,您无法控制渲染在不同平台上的工作方式,特别是字体的呈现方式。

利用appropriate layout managers

其他...

分开责任范围。 “滑块”负责...滑动。创建一个除了提供该功能之外什么都不做的组件。然后创建另一个使用此滑块的组件和JTextField来引入扩展功能......

enter image description here

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

答案 1 :(得分:1)

我认为你已经涂过它们了。

这是处理您的UI代码的一种非常糟糕的方式;您正试图通过在面板中的硬编码位置使用硬编码颜色的两个矩形来实现什么?