2016-10-28 181 views
0

好的,所以我一直在研究这个问题一段时间,真的很茫然。在我的程序中,通过创建新的类来扩展某些JComponent s,覆盖它们的paintComponent方法,并将这些类用于对象,从而接近自定义UI外观。然而,这是我迷失的地方。我有一个简单的窗口,要求用户给它一个目录,然后检查目录,并且如果它无法在该位置创建目录,则将文本字段的颜色(名称为DraconicTextField,将其扩展为JTextField)更改为红色。我正在两台电脑上开发这个工具,使用git来交叉。这个在Windows上工作,但在Linux上失败。下面是代码:JTextField super.paintComponent()在Linux上会忽略背景颜色

class DraconicTextField extends JTextField { 

    private static final long serialVersionUID = 1L; 

    private static final int arcSize = 13; 

    final Color textColor = new Color(31, 31, 31); 
    final Color boxColor = new Color(250, 250, 250); 
    final Color borderColor = new Color(250, 250, 250, 0); 

    public DraconicTextField() { 
     this.setOpaque(false); //true gives the same result, but corners aren't rounded if set as such 
     this.setForeground(textColor); //Text color 
     this.setBackground(boxColor); //BG color 
     this.putClientProperty(SwingUtilities2.AA_TEXT_PROPERTY_KEY, null); 

     this.setFont(new Font("Arial", Font.PLAIN, 18)); 
     this.setFont(GUIUtils.getDefaultFont(this).deriveFont(Font.PLAIN, 18f)); //GUIUtils is imported 

     this.setBorder(new DraconicRoundBorder(arcSize, borderColor)); 

    } 

    @Override 
    public void paintComponent(Graphics graphics) { 
     Graphics2D graphics2d = (Graphics2D) graphics; 

     graphics2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     graphics2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 

     graphics2d.setColor(this.getBackground()); 
     graphics2d.fillRoundRect(0, 0, this.getWidth(), this.getHeight(), arcSize, arcSize); 

     super.paintComponent(graphics2d); //I am almost certain this is the problem-causer 

    } 

} 

为了节省一些空间,主框架类只在发现的目录中invald调用gamedirBox.setBackground(/*some color*/)。 (这是我确定的作品!)

在我的测试中,我做了一个简短(格式非常严格)的程序,看看是否实际上我可以改变颜色,而且我可以,但是这不会覆盖paintComponent方法。 请注意,这段代码是而不是上面代码的一部分!这里是代码:

class GuiBox extends JFrame { 

    public JLabel thisIsTheLabel = this.label("Hello again, world!"); 
    public JTextField testBox = new JTextField(); 
    public JButton testButton = new JButton("Change the color!"); 

    private Random randy = new Random(); 

    public GuiBox(String title) { 
     super(title); 

     this.setSize(300, 400); 
     this.setLayout(new FlowLayout()); 

     testBox.setMinimumSize(new Dimension(200, 40)); 
     testBox.setPreferredSize(new Dimension(200, 40)); 
     testBox.setText("This is some really long string so that flow layout stops being a ****."); 

     testBox.setBackground(new Color(240, 240, 240)); 

     testButton.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent arg0) { 
       testBox.setBackground(new Color(randy.nextInt(255), randy.nextInt(255), randy.nextInt(255))); 
       testBox.repaint(); //Notice, I do not override paintComponent() 

      } 


     }); 

     this.add(testBox); 
     this.add(testButton); 

     this.setVisible(true); 

    } 

    public static void createBox() { 
     GuiBox window = new GuiBox("test box"); 

    } 

} 

谢谢吨的帮助,伙计们!

编辑 - 截图:

的Windows: Windows Functionality

的Linux: Linux Functionality

+0

super.paintComponent()将清除背景。所以你在该陈述之前完成的所有自定义绘画都将丢失。 – camickr

+0

@camickr这是特定的在Linux上摆动?就像我之前提到的那样,它可以在windows上工作,所以这会导致我想象super.paintComponent()在这种情况下使用getBackground()作为颜色,但在这里还有其他的东西。此外,该框仍然是一个圆角矩形,所以我不会想象它会完全清除它。另外,我忘了提及,如果这有什么不同,那么这就是SE 8。不过谢谢! – Drayux

+0

忽视我的第一个评论是错误的。 – camickr

回答

1
public JTextField testBox = new JTextField(); 

您发布甚至不使用自定义文本字段中的代码。

如果您确实使用自定义文本字段,即使在Windows上,它仍然无法正常工作。

this.setOpaque(false); 

以上声明说明组件不绘制自己的背景。因此,您只会看到父组件的背景。

也许代码似乎工作,因为您的自定义边框,但文本组件本身不会绘制背景。

+0

不幸的是,这仍然不起作用。正如我在帖子中提到的(抱歉,如果它不够清楚)第二块代码是一个*独立的*程序* * *工作,所以我可以得出结论,问题是在我的自定义文本字段中的某个地方。我会尽快在这里添加一些截图,但在setOpaque(false)的Windows上仍然有着色。我可能是错的,但我意识到将它设置为不在超类paint组件中绘制它自己的背景正是我想要的,所以我可以像我一样绘制自己的背景。 – Drayux