JLabel - 切断图像的顶部

JLabel - Cutting Off The Top of Image

在我的新 Java 项目中,我有一个 JFrame,其中有一个 JLabel 设置为带有 BorderLayout 的 North,它下面是一个图像。该图像在 JFrame 上很合适,但 JLabel 切掉了它的顶部。我如何调整这个 JLabel 的大小?我试过 setPreferredSize 但没用。帮助将不胜感激。

代码:

    package counter.main;

    import java.awt.BorderLayout;
    import java.awt.Component;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.Font;
    import java.awt.Image;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.io.IOException;
    import java.net.URL;

    import javax.sound.sampled.AudioInputStream;
    import javax.sound.sampled.AudioSystem;
    import javax.sound.sampled.Clip;
    import javax.sound.sampled.LineUnavailableException;
    import javax.sound.sampled.UnsupportedAudioFileException;
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingConstants;

    public class FoodCounter {

    public static JLabel greet4 = new JLabel("",SwingConstants.CENTER);
    public static JLabel message4 = new JLabel();
    public static JLabel lclicks4  = new JLabel();
    public static JButton buttonClick4 = new JButton("+ Food");
    public static int clicks4 = 0;
    public static URL food =           Main.class.getResource("/counter/main/FoodEating.wav");
    public static JButton back = new JButton("Back");
    public static JLabel bread;

    static JFrame frame = new JFrame("Food Counter"); {
        createView();

        frame.setSize(500, 100);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.revalidate();
        frame.repaint();
    }

    private void createView() {
        final JPanel panelc = new JPanel();
        frame.getContentPane().add(panelc);

        panelc.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 11));

        greet4.setFont(new Font( "Dialog", Font.PLAIN, 18));
        greet4.setPreferredSize(new Dimension(40, 20));

        panelc.add(message4);

        frame.add(back, BorderLayout.WEST);
        frame.add(greet4, BorderLayout.NORTH);
        back.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                frame.setVisible(false);
                SelectionFrame.frame1.setVisible(true);
            }

        });

        panelc.add(buttonClick4);
        panelc.add(lclicks4);
        updateCounter();

        bread = new JLabel("");
        bread.setPreferredSize(new Dimension(64, 64));
        Image img = new ImageIcon(this.getClass().getResource("/counter/main/SlicedBread64.png")).getImage();
        bread.setIcon(new ImageIcon(img));
        frame.getContentPane().add(bread, BorderLayout.EAST);

        buttonClick4.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                clicks4++;
                updateCounter();
                try {
                AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(food);
                Clip clip = AudioSystem.getClip();
                clip.open(audioInputStream);
                clip.start();
                } catch (IOException | UnsupportedAudioFileException |  LineUnavailableException x) {
                    x.printStackTrace();
                }
                }
            });

        };

    private void updateCounter() {
        lclicks4.setText(clicks4 + "/100 Food  ");

        if (clicks4 < 1) {
            message4.setText("Click to Begin! -->");
        }

        if (clicks4 >= 1 && clicks4 < 10) {
            message4.setText("Keep Going!");
        }

        if (clicks4 >= 10 && clicks4 < 50) {
            message4.setText("Keep 'em Comin'!");
        }

        if (clicks4 >= 50 && clicks4 < 70) {
            message4.setText("Don't Stop!");
        }

        if (clicks4 >= 70 && clicks4 < 80) {
            message4.setText("Almost!");
        }


        if (clicks4 >= 90 && clicks4 < 100) {
            message4.setText("Finish Strong!");
        }

        if (clicks4 >= 100) {
            try {
                Thread.sleep(3000);                 
            } catch(InterruptedException ex) {
                Thread.currentThread().interrupt();
            }
            System.exit(0);
        }
    }       
}
  • 不要在组件上设置大小、首选大小或类似问题,top-level windows 如果可以避免的话。
  • 相反,通过巧妙地使用布局管理器并在添加所有组件之后调用 setVisible(true) 之前在 top-level window 上调用 pack(),让 GUI 自行调整大小。
  • 考虑将虚拟文本放入 greet4 JLabel,以便在打包 GUI 时占用 space。一些 space," " 可能就足够了。

不相关的推荐:

  • 你的大部分变量应该是 instance 变量,而不是 static 变量。 Java 是根据 object-oriented 编程原则构建的,原因有很多,但主要的原因是减少连接及其相关的复杂性。通过使用静态变量和方法,您可以消除这种好处并冒着创建具有高度圈复杂度的程序的风险,从而使调试变得困难。
  • 声明为 public 的变量也是如此。更喜欢使用 private 字段来帮助减少耦合并增加内聚性。
  • 运行 long-running 代码(例如播放音乐的代码)在后台线程中以避免占用 Swing 事件线程。
  • 切勿在 Swing 事件调度线程或 EDT 中调用 Thread.sleep(...),因为这会使整个 Swing GUI 进入休眠状态。

例如,

import java.awt.BorderLayout;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
public class FoodCounter2 extends JPanel {
   public static final String IMAGE_PATH = "https://duke.kenai.com/iconSized/duke.gif";
   private static final Font TITLE_FONT = new Font("Dialog", Font.PLAIN, 18);
   private JLabel titleLabel = new JLabel("Welcome, User", SwingConstants.CENTER);
   private JButton backButton = new JButton("Back");
   private JButton addFoodButton = new JButton("+ Food");
   private JLabel foodCountLabel = new JLabel("0/100 Food");

   public FoodCounter2() throws IOException {
      URL imgUrl = new URL(IMAGE_PATH);
      BufferedImage img = ImageIO.read(imgUrl);
      ImageIcon icon = new ImageIcon(img);

      JPanel foodPanel = new JPanel(new GridBagLayout());
      // JPanel foodPanel = new JPanel();
      GridBagConstraints gbc = new GridBagConstraints();
      gbc.weightx = 1.0;
      gbc.weighty = 1.0;
      gbc.gridx = 0;
      gbc.gridy = 0;
      gbc.insets = new Insets(10, 10, 10, 10);
      foodPanel.add(new JLabel("Click to Begin! --->"), gbc);
      gbc.gridx++;
      foodPanel.add(addFoodButton, gbc);
      gbc.gridx++;
      foodPanel.add(foodCountLabel, gbc);

      JPanel centerPanel = new JPanel(new BorderLayout());
      titleLabel.setFont(TITLE_FONT);
      centerPanel.add(titleLabel, BorderLayout.PAGE_START);
      centerPanel.add(foodPanel, BorderLayout.CENTER);

      setLayout(new BorderLayout());
      add(backButton, BorderLayout.LINE_START);
      add(centerPanel, BorderLayout.CENTER);
      add(new JLabel(icon), BorderLayout.LINE_END);

   }

   private static void createAndShowGui() {
      FoodCounter2 mainPanel  = null;
      try {
         mainPanel = new FoodCounter2();
      } catch (IOException e) {
         e.printStackTrace();
         System.exit(-1);
      }

      JFrame frame = new JFrame("FoodCounter2");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

显示为:

这是正在发生的事情:

如您所见,面包的顶部被切掉了。我认为这是因为 JPanel 正在覆盖它。