在 JScrollPane 中按比例绘制图像
Posted
技术标签:
【中文标题】在 JScrollPane 中按比例绘制图像【英文标题】:Drawing an image in JScrollPane within scale 【发布时间】:2013-12-13 18:39:06 【问题描述】:我有一个滚动窗格来加载图像。我不会用她的自然尺寸这张图片,如果这张图片太大,我不会激活滚动条,但是这条指令
g.drawImage(immagine, 0, 0, getWidth(), getHeight(), this);
用于放置在滚动窗格中的缩放图像。我能做什么?
类桂:
导入 java.awt.*; 导入 java.awt.event.*; 导入java.io.File; 导入 javax.swing.*; 公共类 Gui 实现 ActionListener 私有 JFrame frmEditor; 私有 Mappa 内容; 私人 JMenuItem mntmSfondo; 私有 JScrollPane 可滚动; /** *启动应用程序。 */ 公共静态无效主要(字符串[]参数) EventQueue.invokeLater(new Runnable() 公共无效运行() 尝试 Gui 窗口 = new Gui(); window.frmEditor.setVisible(true); 捕捉(异常 e) e.printStackTrace(); ); /** * 创建应用程序。 */ 公共桂() 初始化(); /** * 初始化框架的内容。 */ 私人无效初始化() frmEditor = new JFrame(); frmEditor.setFont(UIManager.getFont("TextArea.font")); frmEditor.setBounds(50, 50, 1024, 768); frmEditor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frmEditor.getContentPane().setLayout(new BorderLayout(0, 0)); JPanel panelTile = new JPanel(); panelTile.setLayout(new BorderLayout(0, 0)); 内容 = 新 Mappa(null); content.setMinimumSize(新维度(150, 150)); 可滚动 = 新 JScrollPane(内容); frmEditor.getContentPane().add(scrollabile, BorderLayout.CENTER); inizializzaMenu(); /** * 初始化菜单。 */ 私人无效 inizializzaMenu() JMenuBar menuBar = new JMenuBar(); frmEditor.setJMenuBar(menuBar); JMenu mnAltro = new JMenu("修改"); menuBar.add(mnAltro); mntmSfondo = new JMenuItem("加载背景"); mntmSfondo.addActionListener(this); mnAltro.add(mntmSfondo); 公共无效actionPerformed(ActionEvent e) 对象源 = e.getSource(); 如果(来源 == mntmSfondo) JFileChooser fc = new JFileChooser("tuttiSfondi"); int 结果 = fc.showOpenDialog(null); 如果(结果 == JFileChooser.APPROVE_OPTION) 文件文件 = fc.getSelectedFile(); 尝试 内容.setImage(文件); //content = new Mappa(file); //scrollabile.setViewportView(content); 捕捉(异常前) 如果(结果 == JFileChooser.CANCEL_OPTION)类映射:
导入 java.awt.*; 导入 java.awt.image.BufferedImage; 导入java.io.*; 导入 javax.imageio.ImageIO; 导入 javax.swing.*; 公共类 Mappa 扩展 JPanel BufferedImage 想象; 公共Mappa(文件fileImmagine) if (fileImmagine != null ) 缓冲图像 img = null; 尝试 img = ImageIO.read(new File(fileImmagine.getPath())); 捕捉(IOException e) e.printStackTrace(); this.immagine = img; 重绘(); 公共无效 setImage(文件文件)抛出 IOException this.immagine = ImageIO.read(file); 字符串名称 = file.getPath(); System.out.println(name); 重绘(); 公共无效paintComponent(图形g) super.paintComponent(g); g.clearRect(0, 0, 4000, 4000); g.drawImage(this.immagine, 0, 0, getWidth(), getHeight(), this); System.out.println("在 Mappa 上调用 Repaint()");【问题讨论】:
【参考方案1】:JScrollPane
,或更确切地说,JViewport
将使用组件(或在本例中为“视图”)的首选大小作为确定视图应该有多大的基础。
当视图扩展超出滚动窗格的大小时,它将显示滚动条。
所以基本上,你需要覆盖public class Mappa extends JPanel
面板的getPreferredSize
,例如
public class Mappa extends JPanel
//...
public Dimension getPreferredSize()
return immagine == null ? new Dimension(200, 200) : new Dimension(immagine.getWidth(), immagine.getHeight());
//...
这将鼓励JViewport
始终与图像大小相同。
还有两件事……
首先,你不应该依赖幻数,例如
g.clearRect(0, 0, 4000, 4000);
应该更像...
g.clearRect(0, 0, getWidth(), getHeight());
其次,
super.paintComponent(g);
无论如何都会这样做,所以调用clearRect
是毫无意义的......
你可能还想看看Scrollable
,但这是一个相当高级的话题
【讨论】:
我错过了一点,如果我需要JScrollPane
对图像的视图做出反应,为什么还要使用JPanel
并覆盖paintComponent
函数! JLabel
已经在为我做这件事了。不是一点不必要的开销。 :(
@Sage 我只是根据 OP 所做的事情来回答,希望我们可以教他们一些有关事情在此过程中如何运作的知识。是的,除非您正在进行某种处理和/或动态调整大小,否则JLabel
通常是更好的方法。但多年后,我倾向于不使用JLabel
这么多......因为我想做图像的动态重新缩放:P
你的回答从一开始对我来说就更清楚了,偏离了方向。只是想说,然后说:)
添加覆盖的方法 getPreferedSize() 我解决了滚动条的问题。谢谢。但是我需要加载一个具有她真实尺寸的图像,这个问题仍然没有解决。例如:我有图像 1920*1080,我的 JFrame 在这里初始化:frmEditor.setBounds(50, 50, 1024, 768);所以我的图像被缩放了......
@MadProgrammer 是的,我知道在这种情况下指令 g.clearRect(...) 是愚蠢的。它是糟糕编程的残余。我非常非常初学者。 :-) 感谢您的耐心等待。【参考方案2】:
我不会用她的自然尺寸这张图片,如果这张图片太 大,我不会激活滚动条,
使用JLabel
包含图像并将其包装在JScrollPane
中应该可以轻松实现您想要的。从以下示例中获取提示:
class AFrame extends JFrame
public AFrame()
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Image view Demo with JScrollPane");
ImageIcon image = new ImageIcon("myImage.png"); // pass the file location of an image
JLabel label = new JLabel(image);
JScrollPane scrollPane = new JScrollPane(label);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
add(scrollPane, BorderLayout.CENTER);
pack();
public static void main(String[] args)
SwingUtilities.invokeLater(new Runnable()
@Override
public void run()
new AFrame().setVisible(true);
);
【讨论】:
我想我不能使用这个方法,因为我需要在这个图像上绘制。我用它作为背景。以上是关于在 JScrollPane 中按比例绘制图像的主要内容,如果未能解决你的问题,请参考以下文章