2014-10-17 66 views
1

我想繪製大於JFrame的圖形,並使用JScrollPane滾動整個圖形。我用兩行創建了一個簡單的例子。滾動條出現,但圖形不顯示。JScrollPane&Graphics2D

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); 
} 
} 

回答

3

歡迎的原因null佈局吮吸一個很好的例子......使用null佈局

避免,像素完美的佈局是現代的UI設計中的錯覺。影響組件的個體大小的因素太多,其中沒有一個可以控制。搖擺設計爲核心與佈局管理工作,丟棄這些會導致沒有問題,問題是,你將花費更多的時間,試圖結束整頓

另見Why is it frowned upon to use a null layout in SWING?瞭解更多詳情...

基本問題是,JScrollPaneJViewport實際上包含您的組件。 JViewport使用您的組件大小提示來確定應該有多大,並使用JViewport決定是否需要顯示滾動條。JScrollPane使用決定。

JViewport正在查看您的組件,並已決定,因爲您還沒有告知它,它應該是0x0的大小。

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

開始通過重寫的getPrefferedSize方法在Test面板並返回一些適當的大小

接下來,調用super.paintComponent你執行任何自定義塗裝前,否則你會與一些真棒,但煩人,油漆文物最終...

ScrollPane

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); 
    } 
} 

你可能會想看看在Scrollableinterface下一個,這樣你就可以控制JViewport的默認大小,所以它不會試圖填滿整個屏幕。

看看Implementing a Scrolling-Savvy Client更多細節

+0

你又打了我一次。 – user1803551 2014-10-17 00:25:27

+0

@ user1803551只需10分鐘;) – MadProgrammer 2014-10-17 00:26:08

+0

這就像永恆在這裏...... – user1803551 2014-10-17 00:27:00

0

的問題來自於線

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

你加入testpanel它默認使用FlowLayout。此佈局不會拉伸其中的組件,因此您繪製的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請記住,如果尺寸太大,它們會「流出」屏幕。