【问题标题】:Scrollable JPanel Without a Layout Manager没有布局管理器的可滚动 JPanel
【发布时间】:2022-06-29 01:33:51
【问题描述】:

我想在可垂直和水平滚动的 JPanel 上显示正弦曲线。如果没有布局管理器,我该如何实现?

请看下面的代码。我需要一个垂直滚动条来查看正弦曲线的底部。

不使用布局管理器很重要。

提前致谢。

package drawsinus;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class DrawSinus extends JPanel
{
       private static double[] x;
       private static double[] y;
       private static JFrame frame = new JFrame();
       private static JPanel panel = new DrawSinus(); 
       
       public void paintComponent(Graphics g) 
       {
             super.paintComponent(g);
      
             Image img = generateSinus();
             g.drawImage(img, 20,20, this);
     
       }
       private Image generateSinus() 
       {
      
             BufferedImage bufferedImage = new BufferedImage(600, 600, BufferedImage.TYPE_INT_RGB);
             Graphics g = bufferedImage.getGraphics();
             x = new double[200];
             y = new double[200];
             for (int t=0; t<=199; t++)
             {                 
                 x[t]= (double)t;
                 y[t] = 300*Math.sin(2*Math.PI*1*t/200);              
             }
             for (int t=0; t<x.length; t++)
             {                   
                 g.fillOval((int)x[t] + bufferedImage.getWidth()/2, -1*((int)y[t]) + bufferedImage.getHeight()/2, 20, 20);                         
             }
            
             return bufferedImage;
      
       }
       public static void main(String[] args) 
       {
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.setSize(800,600);
             frame.setLayout(null);
             frame.setLocationRelativeTo(null);
             frame.setVisible(true);

             panel.setLayout(null);
             panel.setBounds(20, 20, 600, 400);
             panel.setBackground(Color.BLACK);

             frame.add(panel);

             JScrollPane scrPane = new JScrollPane(panel);
             scrPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
             scrPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
             frame.add(scrPane);

             new DrawSinus().generateSinus();
            
       }
    
}

【问题讨论】:

  • @user16320675。感谢您的更正。 1) 删除最后一行; 2) panel 只添加到scrPane; 3) 为面板设置首选尺寸; 4)设置scrPane的边界; 5)框架在最后一行设置为可见(我认为这就是你的意思)。现在,我可以看到滚动条,但我只能滚动一点。我需要滚动并查看正弦曲线的底部。使用布局管理器,我得到了意想不到的结果。我无法将组件放置在正确的坐标上,也无法设置组件的大小和边界。这就是为什么我更喜欢手动调整组件的原因。

标签: java swing layout jpanel scrollable


【解决方案1】:

这是一个可以如何完成的最小示例。

滚动窗格内的组件必须实现Scrollable 接口或设置首选大小,滚动窗格用于确定其视口视图的大小。

我更喜欢覆盖 getPreferredSize,因此它动态会在图像发生变化时发生变化(在这个最小的示例中不可能)并避免首选大小在外部发生变化setPreferredSize().

public class DrawSinus2 {

    public static void main(String[] args) {
        // Swing's Thread Police: All Swing components and related classes, unless
        // otherwise documented, must be accessed on the event dispatching thread.
        SwingUtilities.invokeLater(DrawSinus2::initGUI);
    }
    
    private static void initGUI() {
        // Panel to draw image
        JPanel sinusPanel = new JPanel() {
            private final Image image = generateSinus();
            
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (image != null) {
                    g.drawImage(image, 0, 0, this);
                }
            }
            
            // Preferred size used by scroll pane
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(image.getWidth(this), image.getHeight(this));
            }
        };

        // Scroll pane containing the image panel
        JScrollPane scrPane = new JScrollPane(sinusPanel);
        scrPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
        scrPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
        scrPane.setBounds(0, 0, 600, 400);

        // Main frame displaying the scroll pane
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(null);
        frame.setSize(800, 600);
        frame.add(scrPane);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
    
    private static Image generateSinus() {
        // generate and return some image
    }
}

【讨论】:

    猜你喜欢
    • 2016-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-09
    • 2010-11-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多