2011-11-09 125 views
2

我有一个JScrollPane内的JPanel的东西。我在JPanel中绘制事物,并且在某些时候我可能会绘制超过JScrollPane的宽度。在这种情况下,我希望水平滚动条出现,我希望能够滚动查看JPanel的不同部分。但是,我最终清除了JScrollPane。调整大小一个JScrollPane里面一个JPanel,清除我画上的JPanel

frame = new JFrame(); 
frame.setBounds(100, 100, 1000, 800); 
localScrollPane = new JScrollPane(); 
localScrollPane.setBounds(768, 6, 226, 350); 
frame.getContentPane().add(localScrollPane);   
localView = new JPanel(); 
localScrollPane.setViewportView(localView); 

drawSomeThings(localView.getGraphics()); 
// wait for user input 
int newWidth = drawThingsPastTheWidth(localView.getGraphics()); 

// these next two lines clear it 
localView.setPreferredSize(new Dimension(newWidth, localView.getHeight())); 
localView.revalidate(); 

我在做什么错?谢谢!

+0

不使用的getGraphics - 据我所知,这将只是生产出最有可能将超过涂(与补偿的背景)下一次的paintComponent在内部调用快照。相反,请保留产生绘图的状态并在paintComponent中从该状态重绘。如果速度太慢,请勾选bufferedImage并绘制图像(如果没有其他变化) – kleopatra

回答

4
drawSomeThings(localView.getGraphics()); 

不要使用的getGraphics()方法来作画。下一次Swing确定组件需要重新绘制时,绘画将会丢失。

相反的风俗画是通过覆盖你的组件的paintComponent()方法来完成。

+0

+1:可能是这个问题。我只专注于尺寸问题... – Heisenbug

+0

啊,所以我应该扩展JPanel(或JComponent)而不是直接绘制到JPanel? – Vinay

+0

是的。 [自定义绘画](http://download.oracle.com/javase/tutorial/uiswing/painting/step2.html)教程将指导您完成整个过程。 – camickr

0

这样看来,重绘被称为在某些时候,我没有用摆了一段时间,所以我不能完全确定是什么问题,但尝试调试,并通过代码一步一步运行看到重绘被称为是一个很好的起点。

+0

您的意思是重绘或重绘?我认为它调用repaint()作为重新验证的一部分(需要检查以确保)或者当我滚动条。但即使知道它调用repaint(),解决方案是什么?我是否需要将所有东西都绘制回localView的图形对象,还是有更好的方法?例如,如果用户使用箭头键滚动,每次用户滚动时手动重新绘制所做的所有操作都效率低下且速度非常慢。 – Vinay

+0

就像我说过的,自从我使用swing之后已经有一段时间了,所以对于可能存在的问题我非常生疏,但可能repaint()是被调用的方法。我不确定什么是最好的方法,显然重新绘制屏幕效率不高,但至少它会起作用,我只是认为指引你朝着正确的方向可能会帮助你,对不起。 – mmoon

+0

我当然感谢你的帮助。谢谢:-) – Vinay

2
  1. 请不要使用setPreferredSize方法,这里是related thread
  2. 请勿用setBounds明确指定JScrollPane的大小。让父母的LayoutManager处理这个问题。
  3. JScrollPane中应使用默认ScrollPaneConstants.HORIZONTAL_SCROLLBAR_​​AS_NEEDED一个 。所以 当子组件的首选大小 高于显示区域时,滚动条应自动出现。尝试到 重新验证JScrollPane而不是JPanel。
+0

我明白,通常你应该使用LayoutManager;但我看不出在这种情况下会有什么帮助。我正在绘制localview,这是一个需要可生长的表面;它基本上只是一个画布,我不知道一个布局管理器会检测我是否超过了面板图形对象的边界。 – Vinay

+0

看看@ camickr的回答。我认为这可能是你的问题。顺便说一句,你应该总是使用适当的布局管理器,并且不要使用应用程序代码中的setXXXMethods。如果你依靠这些方法建立你的gui,你会很快就会遇到很多麻烦。 – Heisenbug

0

你当然应该使用重画,而不是重新验证。重新验证仅将顶层的所有容器标记为无效。

+0

调用repaint()而不是rev​​alidate()只是让它清除我已经立即绘制到曲面上的任何东西。 – Vinay

+0

@Vinay - 这清楚地表明你正在做错事:-) – kleopatra