当前位置: 首页 > 知识库问答 >
问题:

在JScrollPanel中使用paintComponent进行绘图

慕容坚
2023-03-14

我被一些奇怪的东西卡住了。我有一个带有JScrollPane的JFrame,其中包含一个比实际屏幕大得多的jPanel。我用圆柱画正方形,我希望这些正方形越过JPanel的右边框。(以便在向右滚动时显示它们。)但是使用paintComponents方法绘制的方块只是在JScrollPane的可见视口处停止。

下面是JFrame内部的JScrollPane的代码

public void initComponents(){

    mainPanel = new DrawPanel(dim);
    this.getContentPane().setLayout(new GridBagLayout());

    GridBagConstraints gbc = new GridBagConstraints();
    gbc.gridheight = 1;
    gbc.gridwidth = 1;
    gbc.gridx = 0;
    gbc.gridy = 0;
    gbc.weighty = 1;
    gbc.weightx = 1;
    gbc.fill = GridBagConstraints.BOTH;


    JScrollPane jsp = new JScrollPane(mainPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    jsp.setLayout(new ScrollPaneLayout());
    jsp.setViewportView(mainPanel);
    jsp.getVerticalScrollBar().setUnitIncrement(20);
    jsp.setBorder(BorderFactory.createEmptyBorder());
    jsp.setPreferredSize(new Dimension(dim.width,dim.height -taskBarSize));
    jsp.setMinimumSize(new Dimension(dim.width,dim.height -taskBarSize));
    jsp.setMaximumSize(new Dimension(dim.width,dim.height -taskBarSize));
    this.getContentPane().add(jsp, gbc);
    this.getContentPane().revalidate();
    this.getContentPane().repaint();




}
private Dimension dim;
private Integer numberPanels = 7;
private Double startPointX;
private Double startPointY;
private Double heightRow;
private Double heightPanel;


public DrawPanel(Dimension d) {
    this.dim = d;
    //this.setBackground(Color.BLACK);
    calculateStartPoint();
}

public void calculateStartPoint() {


    startPointX = (dim.getWidth() / 10) * 1;
    startPointY = (dim.getHeight() / 10) * 1;
    heightRow = (dim.getHeight() * 0.8) / numberPanels;
    heightPanel = heightRow - 10;
    double colums = 366/numberPanels;
    this.setPreferredSize(new Dimension((int)(heightRow *((int)colums + 1)), dim.height ));
    this.setMinimumSize(new Dimension((int)(heightRow *((int)colums + 1)), dim.height ));

}

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);

    g.setColor(Color.GRAY);
    for (int i = 1; i <= 366; i++) {

        // Si c'est le dernier d'une colonne
        if (i%numberPanels == 0 && i != 0) {
            g.fillRect(startPointX.intValue(), startPointY.intValue(), heightPanel.intValue(),
                    heightPanel.intValue());
            startPointX = startPointX + heightRow;
            startPointY = startPointY - ((numberPanels -1) * heightRow);

            // Si c'est encore dans la meme colonne
        } else {
            g.fillRect(startPointX.intValue(), startPointY.intValue(), heightPanel.intValue(),
                    heightPanel.intValue());
            startPointY = startPointY + heightRow;
        }

    }


}

}

同时,调整所有的大小。我还必须看到,当滚动回来时,已经画好的方块消失了,就好像所有屏幕外的东西都消失了。

谢谢有时间的人。

共有1个答案

拓拔富
2023-03-14

您的问题是,您需要重新计算的起点,每次绘画完成。否则,变量就会不必要地增加。所以增加两行:

@Override
protected void paintComponent(Graphics g) { // should be protected
    super.paintComponent(g);

    // need to re-initialize variables within this
    startPointX = (dim.getWidth() / 10) * 1;
    startPointY = (dim.getHeight() / 10) * 1;

在未来,请贴一个MCVE与您的问题。例如,这是我用您的代码制作的MCVE,现在任何人都可以复制、粘贴和运行这些代码:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.*;

@SuppressWarnings("serial")
public class Foo02 extends JPanel {
    private DrawPanel mainPanel;
    private Dimension dim = new Dimension(200, 200);

    public Foo02() {
        initComponents();
    }

    public void initComponents() {
        mainPanel = new DrawPanel(dim);
        // !! this.getContentPane().setLayout(new GridBagLayout());
        setLayout(new GridBagLayout()); // !!
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridheight = 1;
        gbc.gridwidth = 1;
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weighty = 1;
        gbc.weightx = 1;
        gbc.fill = GridBagConstraints.BOTH;
        JScrollPane jsp = new JScrollPane(mainPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        jsp.setLayout(new ScrollPaneLayout());
        jsp.setViewportView(mainPanel);
        jsp.getVerticalScrollBar().setUnitIncrement(20);
        jsp.setBorder(BorderFactory.createEmptyBorder());
        jsp.setPreferredSize(new Dimension(dim.width, dim.height));
        jsp.setMinimumSize(new Dimension(dim.width, dim.height));
        jsp.setMaximumSize(new Dimension(dim.width, dim.height));
        add(jsp, gbc);
        revalidate();
        repaint();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui() {
        Foo02 mainPanel = new Foo02();
        JFrame frame = new JFrame("Foo02");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
}

@SuppressWarnings("serial")
class DrawPanel extends JPanel {
    private Dimension dim;
    private Integer numberPanels = 7;
    private Double startPointX;
    private Double startPointY;
    private Double heightRow;
    private Double heightPanel;

    public DrawPanel(Dimension d) {
        this.dim = d;
        // this.setBackground(Color.BLACK);
        calculateStartPoint();
    }

    public void calculateStartPoint() {
        startPointX = (dim.getWidth() / 10) * 1;
        startPointY = (dim.getHeight() / 10) * 1;
        heightRow = (dim.getHeight() * 0.8) / numberPanels;
        heightPanel = heightRow - 10;
        double colums = 366 / numberPanels;
        this.setPreferredSize(new Dimension((int) (heightRow * ((int) colums + 1)), dim.height));
        this.setMinimumSize(new Dimension((int) (heightRow * ((int) colums + 1)), dim.height));
    }

    @Override
    protected void paintComponent(Graphics g) { // should be protected
        super.paintComponent(g);
        // need to re-initialize variables within this
        startPointX = (dim.getWidth() / 10) * 1;
        startPointY = (dim.getHeight() / 10) * 1;

        g.setColor(Color.GRAY);
        for (int i = 1; i <= 366; i++) {
            // Si c'est le dernier d'une colonne
            if (i % numberPanels == 0 && i != 0) {
                g.fillRect(startPointX.intValue(), startPointY.intValue(), heightPanel.intValue(),
                        heightPanel.intValue());
                startPointX = startPointX + heightRow;
                startPointY = startPointY - ((numberPanels - 1) * heightRow);
                // Si c'est encore dans la meme colonne
            } else {
                g.fillRect(startPointX.intValue(), startPointY.intValue(), heightPanel.intValue(),
                        heightPanel.intValue());
                startPointY = startPointY + heightRow;
            }
        }
    }
}
 类似资料:
  • 问题内容: 我希望这个问题不会太笼统。我知道,要在您上进行绘制,您需要重写该方法,并将所有绘制代码​​放入该方法中。我的问题是为什么!为什么Java似乎不允许/提供使用诸如或方法的绘图?在delphi中,一切都变得如此简单。一定有一个原因我无法弄清楚。 问题答案: 那是因为这就是它的工作方式。它是以此方式设计的。但是我想你的问题是关于“为什么” 请记住,Swing大约在15年前问世。批评之一是该A

  • 我有一个JScroll面板和一个JGroup添加到它。我想绘制到JGroup并使JScrollPane的滚动条在绘图超过面板大小时出现,并且能够垂直和水平滚动绘图。 我尝试过咨询各种论坛和官方文档,并尝试了一些事情(设置边框、首选尺寸等),但似乎都没有产生预期的效果。 我有一个JFrame(附带GridBagLayout,btw.): 相关组件包括: JPanel公司: JScrollPane:

  • 您可以使用图案图章工具为照片赋予手绘外观。 使用图案进行绘画 图案图章工具可使用图案进行绘画。可以从图案库中选择图案或者自己创建图案。 选择图案图章工具。 从“画笔预设”面板中选取画笔。请参阅选择预设画笔。 在选项栏中设置模式、不透明度等 的工具选项。请参阅绘画工具选项。 在选项栏中选择“对齐”以保持图案与原始起点的连续性,即使您释放鼠标按钮并继续绘画也不例外。取消选择“对齐”可在每次停止并开始绘

  • 我正在遵循我上一篇关于绘画的帖子中的建议,即Oracle Swing教程。现在我对何时以及如何调用paintComponent()方法感到困惑。 下面是课程: 教程说,两种重绘方法都是重绘以前的鼠标位置以及新的鼠标位置。我明白,但是paintComponent从何而来?当我们说重绘时,它被调用了吗?如果是这样,为什么不在前面的位置也画一个矩形呢?

  • 我是java图形的新手,很难掌握从一个方法(绘制组件())绘制所有图形的整个概念。我只是很好奇,看看我们是否可以在绘制组件之外绘制图形。这可能吗?是否可以在main方法中写一行,如:fillRect(100,100, 500,400);并让它绘制一个矩形?如果可能,是否根据Java常规? 基本上,我想问的是,你是否可以在paintComponent类之外绘制图形,这是常规的吗。