我试图在JFrame的contentpane中显示一个大图像。我想使图像或内容窗格可滚动,因为图像很大。我尝试使用Jscrollpane并将其添加到contentpane但它不起作用。有人寻找解决方案,但最终找不到解决方案。有人可以指导我吗?我的代码在
下面FinalEnvironment.java
package environment;
import java.awt.*;
import java.net.URL;
import javax.swing.*;
public class FinalEnvironment{
public FinalEnvironment(){
Image Eastlake;
URL EastlakeURL = null;
EastlakeURL = FinalEnvironment.class.getResource("/image1/eastlake_night.png");
Eastlake = Toolkit.getDefaultToolkit().getImage(EastlakeURL);
JFrame frame = new JFrame("UniCat World");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
JMenuBar yellowMenuBar = new JMenuBar();
Map map = new Map(800, 550, Eastlake);
yellowMenuBar.setOpaque(true);
yellowMenuBar.setBackground(Color.YELLOW);
yellowMenuBar.setPreferredSize(new Dimension(800, 50));
frame.setJMenuBar(yellowMenuBar);
JScrollPane scroller = new JScrollPane(map);
scroller.setAutoscrolls(true);
scroller.setPreferredSize(new Dimension(800, 550));
frame.getContentPane().add(scroller, BorderLayout.CENTER);
frame.setSize(800, 600);
frame.setVisible(true);
}
public static void main(String[] args){
FinalEnvironment fe = new FinalEnvironment();
}
}
这是我的map.java
package environment;
import java.awt.*;
import javax.swing.*;
public class Map extends JPanel{
private int width;
private int height;
private Image img;
public Map(int width, int height, Image img){
this.width = width;
this.height = height;
this.img = img;
}
protected void paintComponent(Graphics g)
{
super.paintComponents(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(img,0,0,2624,1696,null);
}
}
最后,我想将Jbuttons放在这张图片的顶部。我应该调用一个矩形并将其放在contentpane中的图像顶部,然后我使用Point来定位我的按钮,还是我应该立即使用图像或组件本身来完成它?我需要按钮能够在内容窗格中滚动而不是静态时与图像同步。
由于
答案 0 :(得分:14)
我会在这做什么:
1.有一个面板(画布),其唯一的责任是在覆盖方法paintComponent()
中独立于实际图像尺寸绘制给定图像
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
2.确保画布首选大小等于图像实际大小。
3.有第二个面板,用作框架的内容窗格。
4.在其中,您将设置JScrollPane
作为其中心。
5.在滚动窗格中,视口将是步骤1中的组件。
6.从步骤1将按钮添加到画布面板。它将与图像一起滚动。
7.将内容窗格(步骤3中的面板)添加到框架中,然后运行该应用程序。
修改强> 带有添加到画布的按钮的代码示例,它始终保持在原位,与滚动位置或帧大小无关。
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class ScrollImageTest extends JPanel {
private static final long serialVersionUID = 1L;
private BufferedImage image;
private JPanel canvas;
public ScrollImageTest() {
try {
this.image = ImageIO.read(new URL("http://interviewpenguin.com/wp-content/uploads/2011/06/java-programmers-brain.jpg"));
}catch(IOException ex) {
Logger.getLogger(ScrollImageTest.class.getName()).log(Level.SEVERE, null, ex);
}
this.canvas = new JPanel() {
private static final long serialVersionUID = 1L;
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, null);
}
};
canvas.add(new JButton("Currently I do nothing"));
canvas.setPreferredSize(new Dimension(image.getWidth(), image.getHeight()));
JScrollPane sp = new JScrollPane(canvas);
setLayout(new BorderLayout());
add(sp, BorderLayout.CENTER);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
JPanel p = new ScrollImageTest();
JFrame f = new JFrame();
f.setContentPane(p);
f.setSize(400, 300);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
});
}
}
答案 1 :(得分:5)
如果您使用尺寸来设置地图的首选尺寸,该怎么办?例如,给Map这个方法:
// method in the Map class
@Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
这样,Map JPanel将占用显示整个图像的必要空间。另外,为什么paintComponent方法中的drawImage方法具有大的 magic 数字?为什么不在那里使用宽度和高度? 编辑1:或者甚至不指定Boro在他的回答中建议的图像大小(1+给他)。
答案 2 :(得分:5)
为什么每个人都在重新发明轮子?不需要自定义面板来绘制图像!!!
您需要做的就是创建一个JLabel并将ImageIcon添加到标签中,您将不会遇到任何问题。标签将:
以(0,0)的原始大小绘制图像(这正是自定义代码的作用)。
根据图像大小确定图像的首选大小。现在滚动会自动发生。
此外,很少有任何理由使用setPreferredSize()方法,因为所有组件都具有默认的首选大小。因此,您不应该设置菜单栏的默认大小。我设置首选大小的唯一时间是JScrollPane。这将允许以合理的大小打包框架,然后根据标签中图像的大小自动显示滚动条。
答案 3 :(得分:3)
除了其他有用的答案之外,您可能还想研究使用鼠标手势滚动任意内容的example。