簡體   English   中英

JScrollPane和Graphics2D

[英]JScrollPane & Graphics2D

我試圖繪制比JFrame大的圖形,並使用JScrollPane滾動整個圖形。 我創建了一個包含兩行的簡單示例。 出現滾動條,但不顯示圖形。

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class Test extends JPanel{

public static void main(String... args) {
    Test test = new Test();
    JFrame frame = new JFrame();
    JPanel panel = new JPanel();
    panel.add(test);
    JScrollPane scrollPane = new JScrollPane(panel);
    scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
    scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    scrollPane.setBounds(0, 0, 1350, 700);
    JPanel contentPane = new JPanel(null);
    contentPane.setPreferredSize(new Dimension(1400, 700));
    contentPane.add(scrollPane);
    frame.setContentPane(contentPane);
    frame.pack();
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    frame.setVisible(true);
}

@Override
protected void paintComponent(Graphics g) 
{
    Graphics2D g2 = (Graphics2D)g;

    g2.drawLine(30,30,30,3000);
    g2.drawLine(30, 400, 500, 3000);
}
}

歡迎來到一個精彩的示例,說明為什么null布局很爛...

避免使用null布局,像素完美布局是現代ui設計中的一種幻覺。 有太多因素會影響組件的單個大小,您無法控制。 Swing旨在與布局經理為核心一起工作,舍棄這些問題不會導致問題和問題的終結,您將花費越來越多的時間來嘗試糾正

另請參見為什么在SWING中使用空布局會讓人皺眉? 更多細節...

基本問題是JScrollPane有一個JViewport ,它實際上包含您的組件。 JViewport使用組件大小調整提示來確定其JViewport ,而JScrollPane使用JViewport做出的決定來確定是否需要顯示滾動條。

JViewport正在查看您的組件,並已決定(因為沒有另行通知)它的大小應為0x0

您可以通過將LineBorder添加到組件setBorder(new LineBorder(Color.RED));來證明這一點setBorder(new LineBorder(Color.RED)); ,您也不會看到它(或者,如果看到的話,它將是一個紅色的小方塊)

首先覆蓋“ Test面板的getPrefferedSize方法,然后返回一些合適的大小

接下來,在執行任何自定義繪畫之前,請調用super.paintComponent ,否則您將得到一些令人敬畏但令人討厭的繪畫工件...

滾動窗格

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test extends JPanel {

    public static void main(String... args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                Test test = new Test();
                JFrame frame = new JFrame();
                JScrollPane scrollPane = new JScrollPane(test);
                frame.add(scrollPane);
                frame.pack();
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.setVisible(true);
            }
        });
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(3000, 3000);
    }



    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;

        g2.drawLine(30, 30, 30, 3000);
        g2.drawLine(30, 400, 500, 3000);
    }
}

接下來,您可能需要看一下Scrollable interface ,以便可以控制JViewport的默認大小,因此它不會嘗試填充整個屏幕。

有關更多詳細信息,請參閱實現精通滾動客戶端

問題出在線路上

JPanel panel = new JPanel();
panel.add(test);
JScrollPane scrollPane = new JScrollPane(panel);

您正在將test添加到默認情況下使用FlowLayoutpanel中。 此布局不會拉伸其中的組件,因此在其上進行繪制的test尺寸為0x0,在滾動窗格中看到的是空panel

要解決此問題,您可以將panel設置為使用BorderLayout來拉伸中心組件:

JPanel panel = new JPanel(new BorderLayout());
panel.add(test);
JScrollPane scrollPane = new JScrollPane(panel);

或直接將test添加到滾動窗格:

JScrollPane scrollPane = new JScrollPane(test);

另外:

  • 覆蓋paintComponent時,始終將super.paintComponent(g)作為第一行。
  • 不要使用空布局(因此不要在組件上設置邊界)。
  • 使用setPreferredSize請記住,如果尺寸太大,它們將“流出”屏幕。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM