Java 在JScrollPanel中使用paintComponent绘制
我真的被一些奇怪的事情缠住了。我有一个JFrame和一个JScrollPane,其中包含一个远大于实际屏幕的jPanel。我用柱画正方形,我想让这些正方形越过jPanel的右边界。(这样,当您向右滚动时,它们就会出现。)但是使用方法paintComponents绘制的正方形只会在JScrollPane的可见视口中停止 以下是我在JFrame中为JScrollPane编写的代码: 公共组件(){ 这是我的JPanel课程: 公共类DrawPanel扩展了JPanel{Java 在JScrollPanel中使用paintComponent绘制,java,swing,paintcomponent,Java,Swing,Paintcomponent,我真的被一些奇怪的事情缠住了。我有一个JFrame和一个JScrollPane,其中包含一个远大于实际屏幕的jPanel。我用柱画正方形,我想让这些正方形越过jPanel的右边界。(这样,当您向右滚动时,它们就会出现。)但是使用方法paintComponents绘制的正方形只会在JScrollPane的可见视口中停止 以下是我在JFrame中为JScrollPane编写的代码: 公共组件(){ 这是我的JPanel课程: 公共类DrawPanel扩展了JPanel{ private Dimens
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;
}
}
}
}
私有维度dim;
私有整数面板=7;
专用双星点;
私人双起点;
私人双高路;
私人双高面板;
公共绘图面板(尺寸d){
this.dim=d;
//这个.背景(颜色.黑色);
calculateStartPoint();
}
公共无效calculateStartPoint(){
startPointX=(dim.getWidth()/10)*1;
起始点=(dim.getHeight()/10)*1;
heightRow=(dim.getHeight()*0.8)/NumberPanel;
高度面板=高度行-10;
双柱=366/个板;
此.setPreferredSize(新尺寸((int)(heightRow*((int)colums+1)),尺寸高度);
此.setMinimumSize(新尺寸((int)(heightRow*((int)colums+1)),尺寸高度);
}
@凌驾
公共组件(图形g){
超级组件(g);
g、 setColor(颜色为灰色);
对于(int i=1;i,您的问题是每次完成绘制时都需要重新计算起点。否则变量会不必要地不断增加。因此,添加两行:
@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,现在任何人都可以复制、粘贴和运行代码:
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.GridBagConstraints;
导入java.awt.GridBagLayout;
导入javax.swing.*;
@抑制警告(“串行”)
公共类Foo02扩展了JPanel{
私人绘图面板主面板;
私有维度dim=新维度(200200);
公共图书馆02(){
初始化组件();
}
公共组件(){
主面板=新的绘图面板(尺寸);
//!!this.getContentPane().setLayout(新的GridBagLayout());
setLayout(新的GridBagLayout());/!!
GridBagConstraints gbc=新的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=新的JScrollPane(主面板,JScrollPane.VERTICAL\u滚动条\u始终,
JScrollPane.水平滚动条(根据需要);
setLayout(新的ScrollPaneLayout());
setViewportView(主面板);
jsp.getVerticalScrollBar().setUnitIncrement(20);
setboorder(BorderFactory.createEmptyByOrder());
setPreferredSize(新维度(dim.width、dim.height));
setMinimumSize(新维度(dim.width,dim.height));
setMaximumSize(新维度(dim.width,dim.height));
添加(jsp、gbc);
重新验证();
重新油漆();
}
公共静态void main(字符串[]args){
调用器(()->createAndShowGui());
}
私有静态void createAndShowGui(){
Foo02主面板=新的Foo02();
JFrame=新JFrame(“Foo02”);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
添加框架(主面板);
frame.pack();
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
}
@抑制警告(“串行”)
类DrawPanel扩展了JPanel{
私有维度;
私有整数面板=7;
专用双星点;
私人双起点;
私人双高路;
私人双高面板;
公共绘图面板(尺寸d){
this.dim=d;
//这个.背景(颜色.黑色);
calculateStartPoint();
}
公共无效calculateStartPoint(){
startPointX=(dim.getWidth()/10)*1;
起始点=(dim.getHeight()/10)*1;
heightRow=(dim.getHeight()*0.8)/NumberPanel;
高度面板=高度行-10;
双柱=366/个板;
此.setPreferredSize(新尺寸((int)(heightRow*((int)colums+1)),尺寸高度);
此.setMinimumSize(新尺寸((int)(heightRow*((int)colums+1)),尺寸高度);
}
@凌驾
受保护的组件(图形g){//应受到保护
超级组件(g);
//需要在此范围内重新初始化变量
startPointX=(dim.getWidth()/10)*1;
起始点=(dim.getHeight()/10)*1;
g、 setColor(颜色为灰色);
对于(int i=1;我请创建并发布一个有效的。哦,我的好,我是一个真正的莫伦,我完全忘记了这个!!多谢大家,我太专注于paintComponents方法了,以至于忘了重新初始化那些点!@nightslit:不客气!注意编辑答案,显示了我创建的一个来帮助解决问题的方法。将来,你会想要的o在你的问题中加入有效的MCVE,使其更容易回答。祝你好运!谢谢你的更正,我下次会这样做。
@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;
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;
}
}
}
}