如何在Java swing中调整面板中的图像? [英] how to adjust image in a panel in Java swing?

查看:133
本文介绍了如何在Java swing中调整面板中的图像?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些代码,在SO中有很多来自其他程序员的帮助。首先,谢谢大家。现在我有这个刽子手的代码。我希望文本字段显示在图像下方,现在它正在它上方拍摄。我在代码中提供了图像的链接。但您可能需要下载它以避免抛出异常。
我想保留右上角免费的计时器,我还没想过该怎么做。
我需要帮助才能将图像和texfield放在正确的位置。请执行代码以查看它当前的外观。我尝试了BorderLayout.SOUTH和BorderLayout.PAGE_END,但它没有帮助谢谢

I have some bits of code with a lot of help from fellow programmers in SO. First off, Thank you all for that. Now I have this code for hangman. I want the textfield to appear below the image, right now it is shooting on top of it. I have provided the link for the image in the code. but you might need to download it to avoid exception thrown. I want to keep top right corner free for timer, which I have not thought how to do yet. I need assistance in getting image and texfield in correct positions. please execute code to see how it looks currently. I tried both BorderLayout.SOUTH and BorderLayout.PAGE_END, but it did not help Thank you

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.text.MaskFormatter;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;

public class HangmanGUI {
   private DetailsPanel myPanel;
   private ImagePanel imagePanel = new ImagePanel();

   public HangmanGUI() throws ParseException {
      myPanel = new DetailsPanel();
      JFrame myframe = new JFrame();
      // myframe.getContentPane().setLayout(new BorderLayout());
      myframe.getContentPane().add(imagePanel, BorderLayout.CENTER);
      myframe.getContentPane().add(myPanel, BorderLayout.SOUTH);
      myframe.setTitle("Hangman Game");
      // myframe.setVisible(true);
      // myframe.setLocationRelativeTo(null);
      myframe.pack();
      myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      myframe.setLocationRelativeTo(null);
      myframe.setVisible(true);
   }

   public static void main(String[] args) throws ParseException {
      new HangmanGUI();
   }
}

class ImagePanel extends JPanel {
   private static final int PREF_W = 400;
   private static final int PREF_H = PREF_W;
   private static final String TITLE = "Hangman Image";
   private BufferedImage image;

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   public ImagePanel() {
      setBorder(BorderFactory.createTitledBorder(TITLE));
      try {
          image = ImageIO.read(new File("http://upload.wikimedia.org/wikipedia/commons/8/8b/Hangman-0.png"));
      } catch (IOException ex) {
           ex.printStackTrace();
      }

      add(createFormattedPanel(),BorderLayout.SOUTH);
  //add(createFormattedPanel(),BorderLayout.PAGE_END);
   }

   @Override
   protected void paintComponent(Graphics g) {
       super.paintComponent(g);
       g.drawImage(image, 0, 0, null); // see javadoc for more info on the parameters            
   }

   public JPanel createFormattedPanel() {
          JPanel panel = new JPanel();
          MaskFormatter formatter = null;
          try {
             JLabel label = new JLabel("Guesss");
             formatter = new MaskFormatter("? ? ? ? ? ? ?");
             formatter.setPlaceholderCharacter('?');
             JFormattedTextField input = new JFormattedTextField(formatter);
             input.setColumns(20);
             panel.add(label);
             panel.add(input);
          } catch (java.text.ParseException exc) {
             System.err.println("formatter is bad: " + exc.getMessage());
             System.exit(-1);
          }

          return panel;
       }

   }

class DetailsPanel extends JPanel {
   public DetailsPanel() {
      setLayout(new BorderLayout());

      setBorder(BorderFactory.createTitledBorder(" click here "));
      //add(createFormattedPanel(), BorderLayout.PAGE_START);

      JPanel letterPanel = new JPanel(new GridLayout(0, 5));
      for (char alphabet = 'A'; alphabet <= 'Z'; alphabet++) {
         String buttonText = String.valueOf(alphabet);
         JButton letterButton = new JButton(buttonText);
         letterButton.addActionListener(clickedbutton());
         letterPanel.add(letterButton, BorderLayout.CENTER);
      }
      add(letterPanel, BorderLayout.CENTER);
   }

   private ActionListener clickedbutton() {
      return new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            String actionCommand = e.getActionCommand();
            System.out.println("actionCommand is: " + actionCommand);
         }
      };
   }

}


推荐答案

因为您将自定义绘画和组件混合到一个组件中,所以您无法控制组件的布局方式。

Because you're mixing custom painting and components into a single component, you are losing control over how your components are laid out.

我想到了两个解决方案。 ..

Two solutions come to mind...

使用 JLabel 显示图像,将其放在 ImagePane CENTER 位置和<中的格式化面板 code> SOUTH position

Use a JLabel to display the image, placing it in the CENTER position of the ImagePane and the "formatted panel" in the SOUTH position

拆分你的用户界面,使每个组件都被隔离......

Split apart your UI so that each component is isolated...

-- Hangman Image --------------
| --------------------------- |
| | ----------------------- | |
| | |                     | | |
| | |                     | | |
| | | (Image Pane)        | | |
| | |                     | | |
| | |                     | | |
| | ----------------------- | |
| | ----------------------- | |
| | | Guess: ? ? ? ? ? ?  | | |
| | ----------------------- | |
| --------------------------- |
| -- click here ------------- |
| |                         | |
| |                         | |
| | (buttons   )            | |
| |                         | |
| |                         | |
| --------------------------- |
-------------------------------

基本上, ImagePane GuessPane ClickPane 都是独立的组件。

Basically, the ImagePane, the GuessPane and the ClickPane are all separate components.

然后你会添加 ImagePane GuessPane 到另一个 JPanel (使用 BorderLayout )然后将此和 ClickPane 添加到主面板上(使用 BorderLayout )。

You would then add the ImagePane and GuessPane onto another JPanel (using BorderLayout) and then add this and the ClickPane onto the main panel (using a BorderLayout).

这将使您更好地控制各个组件的布局方式,并且可以合并。

This will give you greater control over how the individual components are laid out and can be combined.

==示例使用 JLabel ==

== Example Using JLabel ==

这是使用 JLabel 的基本示例使用自定义绘画。

This is a basic example of using a JLabel over using custom painting.

ImagePane GuessPane 是添加到单独的面板,该面板被添加到框架的 CENTER 位置。然后将 DetailsPane 添加到框架的 SOUTH 位置...

The ImagePane and GuessPane are added to separate panel, which is added to the CENTER position of the frame. The DetailsPane is then added to the SOUTH position of the frame...

import javax.swing.*;
import javax.swing.text.MaskFormatter;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.text.ParseException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;

public class HangmanGUI {

    private DetailsPanel myPanel;

    public HangmanGUI() throws ParseException {
        myPanel = new DetailsPanel();
        JFrame myframe = new JFrame();

        JPanel content = new JPanel(new BorderLayout());
        content.add(new ImagePane());
        content.add(new GuessPane(), BorderLayout.SOUTH);
        content.setBorder(BorderFactory.createTitledBorder("Hangman Image"));

        myframe.getContentPane().add(content, BorderLayout.CENTER);
        myframe.getContentPane().add(myPanel, BorderLayout.SOUTH);
        myframe.setTitle("Hangman Game");
        myframe.pack();
        myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myframe.setLocationRelativeTo(null);
        myframe.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }
                try {
                    new HangmanGUI();
                } catch (ParseException ex) {
                    ex.printStackTrace();
                }
            }
        });
    }

    public class ImagePane extends JPanel {

        private JLabel label;

        public ImagePane() {
            setLayout(new BorderLayout());
            label = new JLabel();
            add(label);
            try {
                label.setIcon(new ImageIcon(ImageIO.read(new URL("http://upload.wikimedia.org/wikipedia/commons/8/8b/Hangman-0.png"))));
            } catch (IOException ex) {
                label.setText("Bad Image");
                ex.printStackTrace();
            }
        }

    }

    public static class GuessPane extends JPanel {

        public GuessPane() {
            MaskFormatter formatter = null;
            try {
                JLabel label = new JLabel("Guesss");
                formatter = new MaskFormatter("? ? ? ? ? ? ?");
                formatter.setPlaceholderCharacter('?');
                JFormattedTextField input = new JFormattedTextField(formatter);
                input.setColumns(20);
                add(label);
                add(input);
            } catch (java.text.ParseException exc) {
                System.err.println("formatter is bad: " + exc.getMessage());
                System.exit(-1);
            }
        }

    }

    public static class DetailsPanel extends JPanel {

        public DetailsPanel() {
            setLayout(new BorderLayout());

            setBorder(BorderFactory.createTitledBorder(" click here "));
            //add(createFormattedPanel(), BorderLayout.PAGE_START);

            JPanel letterPanel = new JPanel(new GridLayout(0, 5));
            for (char alphabet = 'A'; alphabet <= 'Z'; alphabet++) {
                String buttonText = String.valueOf(alphabet);
                JButton letterButton = new JButton(buttonText);
                letterButton.addActionListener(clickedbutton());
                letterPanel.add(letterButton, BorderLayout.CENTER);
            }
            add(letterPanel, BorderLayout.CENTER);
        }

        private ActionListener clickedbutton() {
            return new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    String actionCommand = e.getActionCommand();
                    System.out.println("actionCommand is: " + actionCommand);
                }
            };
        }

    }
}

此类型分离需要使用某种模型来跨越组件。

This type of separation is going to require to use some kind of model to bridge across the components.

也就是说,当用户猜测时,你需要更新模型,这将通知其他组件(通过某种监听器API)发生了一些更改,这将允许其他UI元素根据需要自行更新以满足模型的要求。

That is, when the user makes a guess, you need to update the model, which will notify the other components (via some kind of listener API) that some change has occurred, this will allow the other UI elements to update themselves as required to meet the requirements of the model.

模型应该包含游戏的逻辑并驱动UI。

The model should contain the logic for the game and drive the UI.

这篇关于如何在Java swing中调整面板中的图像?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆