簡體   English   中英

JLabel的setBorder方法導致繪制問題

[英]setBorder method for JLabel causing paint problem

我有一個擴展JLabel的自定義類。 對於該類的特定實例,我想在左側的文本上添加一些間距。 我需要間距,因為我正在設置此JLabel的背景,並且我不希望文本在彩色背景的邊緣旁邊突出。 我到處釣魚並實現了這一點(在paint函數內部):

if (condition) {
    bgColor = Color.red;
    setBackground(bgColor);
    setOpaque(true);
    // This line merely adds some padding on the left
    setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0));
}
else {
    setOpaque(false);
}

這似乎起作用,因為它增加了我想要的間距,但是不幸的是,它似乎破壞了整個應用程序其余部分的重新繪制……似乎只有那個特定的組件正在重新繪制,而沒有其余的應用程序。 我最終將其專門跟蹤到setBorder調用...設置任何一種邊框似乎都會導致相同的損壞行為。 我們有兩種不同版本的應用程序,一種在Java 1.5中運行,另一種在Java 1.6中運行,Java 1.6版本似乎可以正常工作,而Java 1.5版本則不能正常工作。 無法將舊版本升級到Java 1.6 ...我需要在Java 1.5中可以使用的功能。 另外,我嘗試了這個(只是看它是什么樣子):

setHorizontalTextPosition(JLabel.CENTER);

而且這似乎也以完全相同的方式中斷了重新繪制。 我瀏覽了應用程序的源代碼,找到了設置邊框的其他位置(包括空邊框),但是在JLabel上找不到任何位置(僅面板,按鈕等)。 有人以前看到過這樣的東西嗎? 知道如何解決? 或者也許是另一種獲取我要求的間距的方法可以解決該錯誤? 謝謝。

問題是您要在paint方法中調用該代碼。 您不應該這樣做,因為它會使EDT凍結,並在揮桿繪畫管道中產生不必要的循環。

您應該將該代碼放在構造函數上,並在應用程序生命周期的其他位置更改組件設計狀態。

如果您想進一步了解Swing繪畫,請閱讀push-pixels.org上的“ Swing繪畫管道”帖子。

請注意,您可以使用BorderFactory.createCompoundBorder組合任意兩個邊框。 然后,您可以使用emptyBorder設置間距,並使用其他間距來繪制外邊界。

編輯:添加示例。

package com.stackoverflow.swing.paintpipeline;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.border.Border;


public class JLabelSetBorderPaintProblem extends JLabel {

    public JLabelSetBorderPaintProblem(String text) {
        super(text);
    }

    /*
     * @see javax.swing.JComponent paint(java.awt.Graphics)
     */
    @Override
    public void paint(Graphics g) {
        super.paint(g);
        // You can not call setBorder here.

        // Please check javadoc.
    }

    /*
     * @see javax.swing.JComponent paintBorder(java.awt.Graphics)
     */
    @Override
    protected void paintBorder(Graphics g) {
        super.paintBorder(g);
        // Here is where the Swing painting pipeline draws the current border
        // for the JLabel instance.

        // Please check javadoc.
    }

    // Start me here!
    public static void main(String[] args) {
        // SetBorder will dispatch an event to Event Dispatcher Thread to draw the
        // new border around the component - you must call setBorder inside EDT.
        // Swing rule 1.
        SwingUtilities.invokeLater(new Runnable() {

            @Override public void run() {
                // Inside EDT
                JFrame frame = new JFrame("JLabel setBorder example");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                // Add the JLabel
                final JLabelSetBorderPaintProblem label = new JLabelSetBorderPaintProblem("Just press or wait...");
                frame.add(label);

                // And change the border...
                label.addMouseListener(new MouseAdapter() {
                    @Override public void mousePressed(MouseEvent e) {
                        label.setBorder(BORDERS.get(new Random().nextInt(BORDERS.size())));
                    }
                });

                // ...whenever you want
                new Timer(5000, new ActionListener() {
                    @Override public void actionPerformed(ActionEvent e) {
                        label.setBorder(BORDERS.get(new Random().nextInt(BORDERS.size())));
                    }
                }).start();

                frame.pack();
                frame.setVisible(true);
            }
        });

    }

    public static final List<Border> BORDERS;
    static {
        BORDERS = new ArrayList<Border>();
        BORDERS.add(BorderFactory.createLineBorder(Color.BLACK));
        BORDERS.add(BorderFactory.createLineBorder(Color.RED));
        BORDERS.add(BorderFactory.createEtchedBorder());
        BORDERS.add(BorderFactory.createTitledBorder("A border"));
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM