首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JLabel组件停留在屏幕上

JLabel组件停留在屏幕上
EN

Stack Overflow用户
提问于 2017-06-21 19:01:02
回答 2查看 186关注 0票数 1

我正在做一个非常基本的条形图,它必须显示6个值。我遇到的问题是,当我把酒吧放在屏幕上,一旦它们停留在屏幕上,我就不能把它们拿下来。我试过使用删除、重新绘制和重新验证函数,但这些都不起作用。

我该怎么做才能把栅栏移开以免堵塞?

我的代码:

代码语言:javascript
复制
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("");
    }
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-06-21 21:17:55

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

  • 在生成首选大小时设置组件的大小--这是布局管理器通常使用的
  • 你在使用null布局,一件非常危险的事情
  • 您正在使用“魔术”数字作为循环结束条件--这是非常危险的事情。如何知道数据数组中只有6个项。简单地使用数据数组的长度有什么害处,就像您以前可能做过的那样?

相反,考虑使用更灵活的代码,以适应任何大小的数据,并避免空布局。例如,考虑以下在JPanel的paintComponent方法中绘制条形图的代码:

代码语言:javascript
复制
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());
    }
}

代码语言:javascript
复制
@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);
    }

}

请注意,如果您调整GUI的大小,条形图将重新调整大小以填充GUI。注意,图表包含任意数量的数据条,这都取决于传递给它的数据数组的长度。

票数 2
EN

Stack Overflow用户

发布于 2017-06-21 19:03:41

您需要重新绘制组件。

代码语言:javascript
复制
getContentPane().validate();
getContentPane().repaint();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44684249

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档