Java JLabel组件保持在屏幕上

Java JLabel组件保持在屏幕上,java,swing,jlabel,Java,Swing,Jlabel,我正在制作一个非常基本的条形图,它必须显示6个值。我遇到的问题是,当我把这些条放在屏幕上时,一旦它们停留在屏幕上,我就无法将它们取下。我尝试过使用remove、repait和revalidate函数,但这些都不起作用 我该怎么做才能移除这些栅栏,以免它们堵塞 我的代码: import javax.swing.*; import java.awt.*; import java.util.Collections; public class BarChart extends JPanel {

我正在制作一个非常基本的条形图,它必须显示6个值。我遇到的问题是,当我把这些条放在屏幕上时,一旦它们停留在屏幕上,我就无法将它们取下。我尝试过使用remove、repait和revalidate函数,但这些都不起作用

我该怎么做才能移除这些栅栏,以免它们堵塞

我的代码:

import javax.swing.*;
import java.awt.*;
import java.util.Collections;

public class BarChart extends JPanel
{
    private JLabel[] bars;

    public BarChart(int[] data)
    {
        update(data);
    }

    public void update(int[] data)
    {
        this.setSize(190, 155);
        this.setLayout(null);

        int max = 0;
        for (int i = 0; i < 6; i++) {if (data[i] > max) {max = data[i];}}

        bars = new JLabel[6];

        for (int i = 0; i < 6; i++)
        {
            bars[i] = new JLabel();
            bars[i].setOpaque(true);
            bars[i].setBackground(Color.RED);

            int height = (max != 0) ? (data[i]*155)/max : 0;
            System.out.printf("%d, %d, %d,... ", height, data[i], max);

            this.add(bars[i]);
            bars[i].setSize(25, height);
            bars[i].setLocation((31*i)+5, 155-height);
        }
        System.out.println("");
    }
}
import javax.swing.*;
导入java.awt.*;
导入java.util.Collections;
公共类条形图扩展JPanel
{
私人JLabel[]酒吧;
公共条形图(int[]数据)
{
更新(数据);
}
公共无效更新(int[]数据)
{
这个。设置大小(190155);
此.setLayout(null);
int max=0;
对于(inti=0;i<6;i++){if(data[i]>max){max=data[i];}
条形=新的JLabel[6];
对于(int i=0;i<6;i++)
{
条[i]=新的JLabel();
条[i].set不透明(真);
条[i].退根地面(颜色.红色);
整数高度=(最大值!=0)?(数据[i]*155)/max:0;
System.out.printf(“%d,%d,%d,…”,高度,数据[i],最大值);
本条增加(条[i]);
钢筋[i]。设置尺寸(25,高度);
钢筋[i]。设置位置((31*i)+5155高度);
}
System.out.println(“”);
}
}

您需要重新绘制组件

getContentPane().validate();
getContentPane().repaint();

对于您当前的代码,您需要调用
removeAll()
,然后JPanel上的
revalidate()
repaint()
将“解决”您的问题,但您还有其他不相关的问题:

  • 当您应该生成首选尺寸时,您正在设置组件的尺寸——这是布局管理器通常使用的
  • 您正在使用
    null
    布局,这是一件非常危险的事情
  • 您正在使用一个“神奇”数字作为for循环结束条件——这是一件非常危险的事情。您如何知道数据数组中有6个项,并且只有6个项。简单地使用数据数组的长度有什么害处,就像您以前可能做过几百次的那样

相反,考虑使用更灵活的代码,该代码适合于您提供的任何大小的数据,并且避免了空布局。例如,考虑下面的代码,这些代码在JPAND的PruttEngult方法中绘制条:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class TestBarChart extends JPanel {
    private static final int[] INIT_DATA = { 1, 2, 4, 5, 6, 9 };
    protected static final int MIN_DATA_lENGTH = 5;
    protected static final int MAX_DATA_LENGTH = 9;
    private static final int MAX_VALUE = 9;
    private static final int PREF_W = 300;
    private static final int PREF_H = 240;
    private BarChart2 barChart2 = new BarChart2(INIT_DATA, MAX_VALUE, PREF_W, PREF_H);

    public TestBarChart() {
        barChart2.setBorder(BorderFactory.createLineBorder(Color.BLUE));

        JPanel chartsPanel = new JPanel(new GridLayout(1, 0));
        chartsPanel.setLayout(new GridLayout(1, 0));
        chartsPanel.add(barChart2);

        JButton resetDataBtn = new JButton(new AbstractAction("Reset Data") {

            @Override
            public void actionPerformed(ActionEvent e) {
                int dataLength = (int) ((MAX_DATA_LENGTH - MIN_DATA_lENGTH) * Math.random()) + MIN_DATA_lENGTH;
                int[] data = new int[dataLength];
                for (int i = 0; i < data.length; i++) {
                    data[i] = (int) (MAX_VALUE * Math.random()) + 1;
                }
                barChart2.setData(data, MAX_VALUE);
            }
        });
        JPanel btnPanel = new JPanel();
        btnPanel.add(resetDataBtn);        

        setLayout(new BorderLayout());
        add(chartsPanel);
        add(btnPanel, BorderLayout.PAGE_END);
    }

    private static void createAndShowGui() {
        TestBarChart mainPanel = new TestBarChart();

        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.GridLayout;
导入java.awt.event.ActionEvent;
导入javax.swing.*;
@抑制警告(“串行”)
公共类TestBarChart扩展了JPanel{
私有静态final int[]INIT_DATA={1,2,4,5,6,9};
受保护的静态最终整数最小数据长度=5;
受保护静态最终整数最大数据长度=9;
私有静态最终整数最大值=9;
专用静态最终整型预调W=300;
私有静态最终整型参数H=240;
private BarChart2 BarChart2=新的BarChart2(初始数据、最大值、预值、预值);
公共测试条形图(){
barChart2.setBorder(BorderFactory.createLineBorder(Color.BLUE));
JPanel chartsPanel=新JPanel(新网格布局(1,0));
chartsPanel.setLayout(新网格布局(1,0));
chartsPanel.add(条形图2);
JButton resetDataBtn=新JButton(新抽象操作(“重置数据”){
@凌驾
已执行的公共无效操作(操作事件e){
int dataLength=(int)((最大数据长度-最小数据长度)*Math.random())+最小数据长度;
int[]数据=新的int[dataLength];
对于(int i=0;icreateAndShowGui());
}
}

@SuppressWarnings(“串行”)
类BarChart2扩展了JPanel{
专用静态最终双杆_宽度=0.90;
私人int prefW;
私有int prefH;
专用静态最终颜色栏\u Color=Color.RED;
私有int[]数据;
私有整数最大值;
公共条形图2(int[]数据、int maxValue、int prefW、int prefH){
setData(数据,最大值);
this.prefW=prefW;
this.prefH=prefH;
}
公共最终无效集合数据(int[]数据,int maxValue){
这个数据=数据;
this.maxValue=maxValue;
重新油漆();
}
public int[]getData(){
返回数据;
}
@凌驾
受保护组件(图形g){
超级组件(g);
g、 设置颜色(条形图颜色);
//放置钢筋位置的简单代数计算
double denom=data.length+1-钢筋宽度;
int barWidth=(int)((getWidth()*BAR_WIDTH)/denom);
对于(int i=0;i
请注意,如果重新调整大小,条形图将重新调整大小以填充GUI
@SuppressWarnings("serial")
class BarChart2 extends JPanel {
    private static final double BAR_WIDTH = 0.90;
    private int prefW;
    private int prefH;
    private static final Color BAR_COLOR = Color.RED;
    private int[] data;
    private int maxValue;

    public BarChart2(int[] data, int maxValue, int prefW, int prefH) {
        setData(data, maxValue);
        this.prefW = prefW;
        this.prefH = prefH;
    }

    public final void setData(int[] data, int maxValue) {
        this.data = data;
        this.maxValue = maxValue;
        repaint();
    }

    public int[] getData() {
        return data;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(BAR_COLOR);

        // simple algebraic calculations on where to place the bars
        double denom = data.length + 1 - BAR_WIDTH;
        int barWidth = (int) ((getWidth() * BAR_WIDTH) / denom);  

        for (int i = 0; i < data.length; i++) {
            int x = (int) (getWidth() * (i + 1 - BAR_WIDTH) / denom);
            int height = (int) (getHeight() * data[i] / (double) maxValue);
            int y = (int) (getHeight() - height);
            g.fillRect(x, y, barWidth, height);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(prefW, prefH);
    }

}