【问题标题】:Preventing Overlay Layout from shifting background image label防止覆盖布局移动背景图像标签
【发布时间】:2016-10-15 18:57:38
【问题描述】:

我有一个 JFrame,上面有一个带有 Overlay Layout 的面板,因为我想设置一个带有图像作为背景的 JLabel 并将东西放在它上面。我将框架的大小设置为等于图像的大小,当我只把它放在它上面时,它非常适合,但是如果我在它上面添加任何东西,它会将图像向右移动我添加的组件的宽度并向右切断。即使组件不在移动的区域中,它也会这样做。该组件位于右侧,并且正确显示在标签上,但图像仍然移动。

    import java.awt.*;       
    import java.*;
    import java.io.*;
    import javax.swing.*;
    import javax.swing.text.*;
    import java.awt.event.*;
    import javax.imageio.*;
    import java.awt.image.*;

    public class MainScreen extends JFrame{  
        JButton button;
        JPanel backgroundPanel, p, panel;

        public MainScreen(ArrayList<Character> c){                  
        JLabel label = new JLabel(new ImageIcon("house.jpg"));
        button = new JButton("Button");

        backgroundPanel = new JPanel();
        p = new JPanel();
        panel = new JPanel();

        p.add(button);  
        panel.add(p);

        panel.setOpaque(false);
        p.setOpaque(false); 

        LayoutManager overlay = new OverlayLayout(backgroundPanel);
        backgroundPanel.setLayout(overlay);

        backgroundPanel.add(panel); 
        backgroundPanel.add(label);        

        add(backgroundPanel);      
        setLocationRelativeTo(null);                 
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setResizable(false);
        setSize(1200, 700);
        setVisible(true);   
        }

        public static void main(String[] args){
        MainScreen ms = new MainScreen(new ArrayList<Character>());
        }
    }

【问题讨论】:

  • 使用逻辑一致的缩进代码行和块的形式。缩进是为了让代码的流程更容易理解!
  • 1) 顺便说一句 - 为什么您之前有 3 个问题的答案,但没有一个已接受的答案?如果它有助于解决问题,请accept an answer。 2) “我将框架的大小设置为等于图像的大小” 这将导致框架太小而无法显示整个图像。您需要考虑框架装饰。
  • @AndrewThompson 很好,当我没有在上面放任何东西时,图像非常适合
  • 1) 为了尽快获得更好的帮助,请发帖 minimal reproducible exampleShort, Self Contained, Correct Example。 2) 例如,获取图像的一种方法是热链接到在this Q&A 中看到的图像。

标签: java swing layout overlay layout-manager


【解决方案1】:

但如果我在其顶部添加任何内容,它会将图像向右移动我添加的组件的宽度并将其切到右侧

您需要使用两个组件的 alignmentX/Y 属性来获得所需的布局。

首先将它们全部设置为 0.5f。

这里有一个小演示程序,可以让你改变属性来看看效果:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

public class OverlayLayoutTest extends JPanel
    implements ActionListener
{
    JPanel green;
    JPanel red;
    JLabel greenLabel;
    JLabel redLabel;
    JComboBox  greenAlignmentX;
    JComboBox  greenAlignmentY;
    JComboBox  redAlignmentX;
    JComboBox  redAlignmentY;

    public OverlayLayoutTest()
    {
        setLayout( new BorderLayout(10, 10) );
        add(createNorthPanel(), BorderLayout.NORTH);
        add(createCenterPanel(), BorderLayout.CENTER);
        add(createSouthPanel(), BorderLayout.SOUTH);
    }

    private JPanel createNorthPanel()
    {
        JPanel panel = new JPanel();

        panel.add( new JLabel("Green:") );
        greenLabel = new JLabel();
        panel.add( greenLabel );

        panel.add( new JLabel("Red:") );
        redLabel = new JLabel();
        panel.add( redLabel );

        return panel;
    }

    private JPanel createCenterPanel()
    {

        JPanel panel = new JPanel();
        panel.setLayout( new OverlayLayout(panel) );
        panel.setBackground( Color.ORANGE );
        panel.setPreferredSize( new Dimension(200, 200) );

        red = new JPanel();
        red.setBackground( Color.RED );
        red.setPreferredSize( new Dimension(50, 50) );
        red.setMaximumSize( red.getPreferredSize() );
        red.setMinimumSize( red.getPreferredSize() );
        panel.add( red );

        green = new JPanel();
        green.setBackground( Color.GREEN );
        green.setPreferredSize( new Dimension(100, 100) );
        green.setMaximumSize( green.getPreferredSize() );
        green.setMinimumSize( green.getPreferredSize() );
        panel.add( green );

        JPanel wrap = new JPanel();
        wrap.add( panel );
        return wrap;
    }

    private JPanel createSouthPanel()
    {
        JPanel panel = new JPanel( new GridLayout(1, 0, 10, 10) );

        JPanel green = new JPanel(new GridLayout(0, 2, 5, 5) );
        green.setBorder( new TitledBorder("Green Alignment") );
        green.add( new JLabel("X Alignment:") );
        greenAlignmentX = createComboBox();
        green.add( greenAlignmentX );
        green.add( new JLabel("Y Alignment:") );
        greenAlignmentY = createComboBox();
        green.add( greenAlignmentY );
        panel.add( green );

        JPanel red = new JPanel(new GridLayout(0, 2, 5, 5) );
        red.setBorder( new TitledBorder("Red Alignment") );
        red.add( new JLabel("X Alignment:") );
        redAlignmentX = createComboBox();
        red.add( redAlignmentX );
        red.add( new JLabel("Y Alignment:") );
        redAlignmentY = createComboBox();
        red.add( redAlignmentY );
        panel.add( red );

        JButton reset = new JButton("Reset Alignment");
        reset.addActionListener( this );
        panel.add( reset );


        return panel;
    }

    public void actionPerformed(ActionEvent e)
    {
        green.setAlignmentX( ((Float)greenAlignmentX.getSelectedItem()) );
        green.setAlignmentY( ((Float)greenAlignmentY.getSelectedItem()) );
        red.setAlignmentX( ((Float)redAlignmentX.getSelectedItem()) );
        red.setAlignmentY( ((Float)redAlignmentY.getSelectedItem()) );
        JPanel parent = (JPanel)green.getParent();
        parent.revalidate();
/*
        System.out.print(green.getAlignmentX() + " : ");
        System.out.print(green.getAlignmentY() + " : ");
        System.out.print(red.getAlignmentX() + " : ");
        System.out.print(red.getAlignmentY() + " : ");
        System.out.println();
*/
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {
                greenLabel.setText( green.getLocation().toString() );
                redLabel.setText( red.getLocation().toString() );
            }
        });

    }

    private JComboBox createComboBox()
    {
        JComboBox<Float> comboBox = new JComboBox<Float>();

        comboBox.addItem( new Float(0f) );
        comboBox.addItem( new Float(0.25f) );
        comboBox.addItem( new Float(0.5f) );
        comboBox.addItem( new Float(0.75f) );
        comboBox.addItem( new Float(1.0f) );
        comboBox.setSelectedItem(0.5f);

        return comboBox;
    }

    private static void createAndShowUI()
    {
        JFrame frame = new JFrame("OverlayLayoutTest");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add( new OverlayLayoutTest() );
        frame.pack();
        frame.setLocationByPlatform( true );
        frame.setVisible( true );
    }

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

另一种选择是将 JLabel 的布局设置为您想要的任何内容(BorderLayout、GridBagLayout、FlowLayout)。然后,您可以将组件直接添加到标签中,就像添加任何面板一样。您添加的任何组件都必须完全包含在标签中。与使用 OverlayLayout 相比,这将为您提供更大的灵活性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-03
    • 1970-01-01
    • 2018-01-27
    • 2014-10-03
    • 2012-09-09
    • 2017-10-25
    • 2016-01-14
    • 1970-01-01
    相关资源
    最近更新 更多