使用 JScrollPane 的 JApplet 滚动条显示但不在屏幕外滚动 Graphics2D 内容
JApplet scrollbar using JScrollPane shows but doesn't scroll Graphics2D content outside screen
我正在尝试向 JApplet 组件添加滚动条。我知道我不应该使用它,而应该使用 JPanel,但为了简单起见,我将保留它,就像我正在关注的教程一样。
如您所见,我尝试添加一个 ScrollPane 组件,并向其添加小程序。然后我将滚动窗格添加到框架中。
结果是我可以看到垂直滚动条,但它确实可以滚动。实际上滚动光标丢失了。上下箭头也不会滚动。我想向下滚动到我绘制的超出可见区域的那部分线。
我做错了什么?
public class App {
private App() {
final int WINHSIZE = 800;
final int WINVSIZE = 600;
class MyJApplet extends JApplet {
public void init() {
setBackground(Color.black);
setForeground(Color.white);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.drawLine(0, 0, 2000, 2000);
}
}
}
JFrame f = new JFrame("Title");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JApplet applet = new MyJApplet();
JScrollPane myScrollPane = new JScrollPane(applet, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
f.getContentPane().add("Center", myScrollPane);
applet.init();
f.pack();
f.setSize(new Dimension(WINHSIZE, WINVSIZE));
f.setVisible(true);
}
public static void main(String[] args) {
new App();
}
}
您已将它们设置为始终可见。这意味着即使不需要滚动 - 它们仍然会出现。如果你不想出现垂直滚动条,你可以这样做:
JScrollPane myScrollPane = new JScrollPane(applet);
或
JScrollPane myScrollPane = new JScrollPane(applet,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
无论您如何实现,滚动条只会在需要时启用和使用。它可能是可见的(如您的代码所示),但启用滚动没有意义,因此它不允许您这样做。
如果确定 applet
的大小大于 myScrollPane
的可用大小,则将激活所需的滚动条。这可以通过添加更多组件或根据需要覆盖 applet
的 setPreferredSize
、setSize
方法来完成。
例如,此代码示例显示了如何仅在需要时激活滚动条(在本例中为水平滚动条)。其余时间,它将可见 - 但不活动 - 这就是您所看到的。
final JFrame frame = new JFrame("Scroll Bar Test");
final JPanel content = new JPanel(new FlowLayout(FlowLayout.LEADING));
final JScrollPane scrollPane = new JScrollPane(content, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
for(int i = 0; i < 10; i++){
content.add(new JLabel("Label " + i));
}
frame.add(scrollPane);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
I'll leave it like it, as in a tutorial I am following.
你的教程太旧了,你不应该继续学习。相反,您应该学习如何以正常方式创建 JFrame。
也就是说,您通过重写 paintComponent()
方法在 JPanel 上进行自定义绘画,然后将面板添加到框架中。你不应该覆盖 paint()。阅读 Custom Painting 上的 Swing 教程(这是一个更好的教程)中的部分以获取更多信息。您需要确保重写 getPreferredSize()
方法,这样滚动条才能正常工作。
f.getContentPane().add("Center", myScrollPane);
这不是您将组件添加到容器的方式。你永远不会硬编码这样的约束。你也应该使用:
add(component, constraint)
BorderLayout 将包含可用于标识约束的字段。
人们不再使用 f.getContentPane().add(...)
。从 JDK4 开始,您可以使用 f.add(...)
。正如我所说,您的教程已经过时了。
查看 Swing 教程的 table 内容。这些示例是最新的,将为您的应用程序提供更好的设计。例如,您应该在事件调度线程上创建 GUI 组件,而您的代码并未这样做。阅读 Concurrency
上的教程,了解为什么这很重要。
我正在尝试向 JApplet 组件添加滚动条。我知道我不应该使用它,而应该使用 JPanel,但为了简单起见,我将保留它,就像我正在关注的教程一样。
如您所见,我尝试添加一个 ScrollPane 组件,并向其添加小程序。然后我将滚动窗格添加到框架中。
结果是我可以看到垂直滚动条,但它确实可以滚动。实际上滚动光标丢失了。上下箭头也不会滚动。我想向下滚动到我绘制的超出可见区域的那部分线。
我做错了什么?
public class App {
private App() {
final int WINHSIZE = 800;
final int WINVSIZE = 600;
class MyJApplet extends JApplet {
public void init() {
setBackground(Color.black);
setForeground(Color.white);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.drawLine(0, 0, 2000, 2000);
}
}
}
JFrame f = new JFrame("Title");
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
JApplet applet = new MyJApplet();
JScrollPane myScrollPane = new JScrollPane(applet, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
f.getContentPane().add("Center", myScrollPane);
applet.init();
f.pack();
f.setSize(new Dimension(WINHSIZE, WINVSIZE));
f.setVisible(true);
}
public static void main(String[] args) {
new App();
}
}
您已将它们设置为始终可见。这意味着即使不需要滚动 - 它们仍然会出现。如果你不想出现垂直滚动条,你可以这样做:
JScrollPane myScrollPane = new JScrollPane(applet);
或
JScrollPane myScrollPane = new JScrollPane(applet,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
无论您如何实现,滚动条只会在需要时启用和使用。它可能是可见的(如您的代码所示),但启用滚动没有意义,因此它不允许您这样做。
如果确定 applet
的大小大于 myScrollPane
的可用大小,则将激活所需的滚动条。这可以通过添加更多组件或根据需要覆盖 applet
的 setPreferredSize
、setSize
方法来完成。
例如,此代码示例显示了如何仅在需要时激活滚动条(在本例中为水平滚动条)。其余时间,它将可见 - 但不活动 - 这就是您所看到的。
final JFrame frame = new JFrame("Scroll Bar Test");
final JPanel content = new JPanel(new FlowLayout(FlowLayout.LEADING));
final JScrollPane scrollPane = new JScrollPane(content, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
for(int i = 0; i < 10; i++){
content.add(new JLabel("Label " + i));
}
frame.add(scrollPane);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
I'll leave it like it, as in a tutorial I am following.
你的教程太旧了,你不应该继续学习。相反,您应该学习如何以正常方式创建 JFrame。
也就是说,您通过重写 paintComponent()
方法在 JPanel 上进行自定义绘画,然后将面板添加到框架中。你不应该覆盖 paint()。阅读 Custom Painting 上的 Swing 教程(这是一个更好的教程)中的部分以获取更多信息。您需要确保重写 getPreferredSize()
方法,这样滚动条才能正常工作。
f.getContentPane().add("Center", myScrollPane);
这不是您将组件添加到容器的方式。你永远不会硬编码这样的约束。你也应该使用:
add(component, constraint)
BorderLayout 将包含可用于标识约束的字段。
人们不再使用 f.getContentPane().add(...)
。从 JDK4 开始,您可以使用 f.add(...)
。正如我所说,您的教程已经过时了。
查看 Swing 教程的 table 内容。这些示例是最新的,将为您的应用程序提供更好的设计。例如,您应该在事件调度线程上创建 GUI 组件,而您的代码并未这样做。阅读 Concurrency
上的教程,了解为什么这很重要。