没有布局管理器的可滚动 JPanel
Scrollable JPanel Without a Layout Manager
我想在可垂直和水平滚动的 JPanel 上显示正弦曲线。如果没有布局管理器,我该如何实现?
请看下面的代码。我需要一个垂直滚动条来查看正弦曲线的底部。
不使用布局管理器很重要。
提前致谢。
package drawsinus;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class DrawSinus extends JPanel
{
private static double[] x;
private static double[] y;
private static JFrame frame = new JFrame();
private static JPanel panel = new DrawSinus();
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Image img = generateSinus();
g.drawImage(img, 20,20, this);
}
private Image generateSinus()
{
BufferedImage bufferedImage = new BufferedImage(600, 600, BufferedImage.TYPE_INT_RGB);
Graphics g = bufferedImage.getGraphics();
x = new double[200];
y = new double[200];
for (int t=0; t<=199; t++)
{
x[t]= (double)t;
y[t] = 300*Math.sin(2*Math.PI*1*t/200);
}
for (int t=0; t<x.length; t++)
{
g.fillOval((int)x[t] + bufferedImage.getWidth()/2, -1*((int)y[t]) + bufferedImage.getHeight()/2, 20, 20);
}
return bufferedImage;
}
public static void main(String[] args)
{
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800,600);
frame.setLayout(null);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
panel.setLayout(null);
panel.setBounds(20, 20, 600, 400);
panel.setBackground(Color.BLACK);
frame.add(panel);
JScrollPane scrPane = new JScrollPane(panel);
scrPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
frame.add(scrPane);
new DrawSinus().generateSinus();
}
}
这里是如何可以完成的最小示例。
滚动窗格内的组件必须实现 Scrollable
接口或设置首选大小,滚动窗格使用它来确定其视口视图的大小。
我更喜欢覆盖 getPreferredSize
,因此它 动态地 如果图像发生变化(在这个最小示例中不可能)并避免使用首选大小 外部 由 setPreferredSize()
更改。
public class DrawSinus2 {
public static void main(String[] args) {
// Swing's Thread Police: All Swing components and related classes, unless
// otherwise documented, must be accessed on the event dispatching thread.
SwingUtilities.invokeLater(DrawSinus2::initGUI);
}
private static void initGUI() {
// Panel to draw image
JPanel sinusPanel = new JPanel() {
private final Image image = generateSinus();
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
g.drawImage(image, 0, 0, this);
}
}
// Preferred size used by scroll pane
@Override
public Dimension getPreferredSize() {
return new Dimension(image.getWidth(this), image.getHeight(this));
}
};
// Scroll pane containing the image panel
JScrollPane scrPane = new JScrollPane(sinusPanel);
scrPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrPane.setBounds(0, 0, 600, 400);
// Main frame displaying the scroll pane
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setSize(800, 600);
frame.add(scrPane);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static Image generateSinus() {
// generate and return some image
}
}
我想在可垂直和水平滚动的 JPanel 上显示正弦曲线。如果没有布局管理器,我该如何实现?
请看下面的代码。我需要一个垂直滚动条来查看正弦曲线的底部。
不使用布局管理器很重要。
提前致谢。
package drawsinus;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class DrawSinus extends JPanel
{
private static double[] x;
private static double[] y;
private static JFrame frame = new JFrame();
private static JPanel panel = new DrawSinus();
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Image img = generateSinus();
g.drawImage(img, 20,20, this);
}
private Image generateSinus()
{
BufferedImage bufferedImage = new BufferedImage(600, 600, BufferedImage.TYPE_INT_RGB);
Graphics g = bufferedImage.getGraphics();
x = new double[200];
y = new double[200];
for (int t=0; t<=199; t++)
{
x[t]= (double)t;
y[t] = 300*Math.sin(2*Math.PI*1*t/200);
}
for (int t=0; t<x.length; t++)
{
g.fillOval((int)x[t] + bufferedImage.getWidth()/2, -1*((int)y[t]) + bufferedImage.getHeight()/2, 20, 20);
}
return bufferedImage;
}
public static void main(String[] args)
{
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800,600);
frame.setLayout(null);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
panel.setLayout(null);
panel.setBounds(20, 20, 600, 400);
panel.setBackground(Color.BLACK);
frame.add(panel);
JScrollPane scrPane = new JScrollPane(panel);
scrPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
frame.add(scrPane);
new DrawSinus().generateSinus();
}
}
这里是如何可以完成的最小示例。
滚动窗格内的组件必须实现 Scrollable
接口或设置首选大小,滚动窗格使用它来确定其视口视图的大小。
我更喜欢覆盖 getPreferredSize
,因此它 动态地 如果图像发生变化(在这个最小示例中不可能)并避免使用首选大小 外部 由 setPreferredSize()
更改。
public class DrawSinus2 {
public static void main(String[] args) {
// Swing's Thread Police: All Swing components and related classes, unless
// otherwise documented, must be accessed on the event dispatching thread.
SwingUtilities.invokeLater(DrawSinus2::initGUI);
}
private static void initGUI() {
// Panel to draw image
JPanel sinusPanel = new JPanel() {
private final Image image = generateSinus();
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
g.drawImage(image, 0, 0, this);
}
}
// Preferred size used by scroll pane
@Override
public Dimension getPreferredSize() {
return new Dimension(image.getWidth(this), image.getHeight(this));
}
};
// Scroll pane containing the image panel
JScrollPane scrPane = new JScrollPane(sinusPanel);
scrPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrPane.setBounds(0, 0, 600, 400);
// Main frame displaying the scroll pane
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.setSize(800, 600);
frame.add(scrPane);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static Image generateSinus() {
// generate and return some image
}
}