Макет Java с компонентом всегда в правом верхнем углу

Основной графический интерфейс моего приложения состоит из JDesktopPane в CENTER панели содержимого фрейма с использованием BorderLayout. Я надеюсь разместить компонент в правом верхнем углу экрана, который по-прежнему позволяет пользователю перетаскивать JInternalFrames в пространство слева и внизу этого компонента.

Установка компонента в NORTH или EAST из BorderLayout, кажется, заполняет все пространство. Я думаю, что BorderLayout, возможно, не лучший менеджер макета для того, что я пытаюсь достичь? Любые предложения о лучшем подходе?

 Tommo01 авг. 2016 г., 19:11
@AndrewThompson Кажется, что он по-прежнему заполняет весь СЕВЕРНЫЙ раздел экрана, несмотря на то, что компонент расположен правильно.
 Tommo01 авг. 2016 г., 18:07
@jameslarge Это правильно, и спасибо, я проверю это.
 Solomon Slow01 авг. 2016 г., 18:06
Просто чтобы прояснить, вы просите менеджер макета, который будет использовать всенепрямоугольная пространство, оставшееся после размещения одного компонента в правом верхнем углу? Я не очень хорошо знаю Swing, но я посмотрю, есть ли какой-нибудь способ, которым вы могли бы использоватьjavax.swing.SpringLayout
 Andrew Thompson01 авг. 2016 г., 18:40
Выровнять по правому краю (панель с)FlowLayout вPAGE_START изBorderLayout, Добавьте выровненный по правому краю компонент на панель с макетом потока.

Ответы на вопрос(1)

Решение Вопроса

ПроверьтеOverlayLayout, Это позволяет вам укладывать компоненты друг на друга.

Вам нужно манипулироватьsetAlignmentX(..) и setAlignmentY (...) `методы, чтобы получить нужный макет. Не всегда интуитивно понятно, как эти выравнивания работают вместе, но установить компонент сверху / слева относительно легко.

Вот небольшая демонстрация для вас:

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();
            }
        });
    }
}
установите значения выравнивания X на 1,0 для обоих компонентовустановите значения Y выравнивания на 0.0 для обоих компонентов

и вы должны получить макет, который вы хотите.

Редактировать:

Пропущена часть о перетаскивании JInternalFrame. Таким образом, это означает, что вы используете JDesktopPane для поддержки перетаскивания. JDesktopPane использует пустой макет, чтобы вы могли перетаскивать компоненты вокруг.

Нет причин, по которым вы не можете добавить другой компонент (кроме JInternalFrame) на рабочий стол. Вам просто нужно установить размер / расположение этого компонента, который будет отображаться в правом верхнем углу рабочего стола. Затем вам нужно будет добавитьComponentListener на панель рабочего стола, чтобы прослушатьcomponentResized событие. Когда это событие вызывается, вам нужно будет пересчитать расположение компонента, чтобы сбросить его в верхнем правом углу.

 Tommo01 авг. 2016 г., 21:17
Спасибо за помощь!
 camickr01 авг. 2016 г., 20:38
@ Tommo, см редактировать, звучит так, как будто вам не нужен OverlayLayout.
 Tommo01 авг. 2016 г., 18:57
Кажется, это работает хорошо, за исключением случая, когда я перетаскиваю JInternalFrame поверх правого верхнего компонента, и это приводит к исчезновению компонента. Наведение мыши на компонент, кажется, заставляет его снова появляться.

Ваш ответ на вопрос