【问题标题】:Drawing an image in JScrollPane within scale在 JScrollPane 中按比例绘制图像
【发布时间】: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()"); } }

【问题讨论】:

    标签: java swing jscrollpane bufferedimage paintcomponent


    【解决方案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);
           }
        });
    
      }
    }
    

    【讨论】:

    • 我想我不能使用这个方法,因为我需要在这个图像上绘制。我用它作为背景。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多