2014-10-17 55 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请记住,如果尺寸太大,它们会“流出”屏幕。