прекратить изменение размера jpanel после изменения размера пользователя - PullRequest
1 голос
/ 13 мая 2011

У меня есть JPanel с JLabel, который часто загружает новую картинку.Я запрограммировал его для изменения размера после каждой загрузки.Тем не менее, я бы хотел, чтобы пользователь мог настроить панель под определенный размер и оставить ее в таком состоянии (при текущих перезагрузках невозможность постоянного изменения размера может ухудшиться).Мой код не работает, хотя:

public class Grapher extends JFrame{        
    private JScrollPane scrollPane;
    private static JPanel topPanel;
    private static JLabel label;
    private static ImageIcon image;

    private static boolean dontResize = false;
    private static boolean firstTime = true;

    public Grapher(){
        setTitle( "some graph" );
        setBackground( Color.gray );
        setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        topPanel = new JPanel();
        topPanel.setLayout( new BorderLayout() );
        getContentPane().add( topPanel );
        label = new JLabel();

        scrollPane = new JScrollPane();
        scrollPane.getViewport().add( label );
        topPanel.add( scrollPane, BorderLayout.CENTER );
        topPanel.addComponentListener(new Listeners());
        topPanel.setName("Soar Grapher Panel");
    }

    public void display(String fileName){
        //steal focus the first time an image is displayed
        if(image == null)
            setVisible(true);
        image = new ImageIcon(fileName);
        image.getImage().flush();
        boolean temp = dontResize;
        setSize(getPreferredSize());
        dontResize = temp;
        System.out.println("afterWards: " + dontResize);
        label.setIcon(image);
        label.repaint();
    }

    @Override
    public Dimension getPreferredSize(){
        if(dontResize){
            System.err.println("not resizing!");
            return getSize();
        }
        if (image == null)
            return new Dimension(100,100);
        else
            return new Dimension(image.getIconWidth() > getWidth() + 40 ? image.getIconWidth() + 40 : getWidth(),
                    image.getIconHeight() > getHeight() + 60 ? image.getIconHeight() + 60 : getHeight());
    }

    private class Listeners implements ComponentListener{

            @Override
            public void componentHidden(ComponentEvent arg0) {}

            @Override
            public void componentMoved(ComponentEvent arg0) {}

            @Override
            public void componentResized(ComponentEvent arg0) {
                System.out.println("componentResized: " + dontResize);
                //TODO make it not resize after the user resizes it themselves.
                System.err.println(arg0.getComponent().getName());
                System.err.println("resized!");
                if(!firstTime)
                    dontResize = true;
                firstTime = false;
            }

            @Override
            public void componentShown(ComponentEvent arg0) {}
    }

}

Я пытаюсь сохранить логическое значение dontResize при изменении размера программы, но, к сожалению, слушатель, кажется, активируется раньше, чем функция resize().Как отличить пользовательское изменение размера от программного изменения размера?

EDIT_ _ __ _ __ Удаление слушателя во время действия программного изменения размера кажетсябыть в пути;однако, слушатель, кажется, вызывается в случайные моменты времени, кроме изменения размера пользователя, все портит.Вот что у меня есть:

private static ComponentListener listeners = new Listeners();
private static boolean resizeOkay = true;
...
[inside the display() function]
    if(resizeOkay){
        removeComponentListener(listeners);
        System.err.println("No handler should be called between here");
        setSize(getPreferredSize());
        System.err.println("and here.");
        addComponentListener(listeners);
    }
    label.setIcon(image);
    label.repaint();
[inside the listener]
@Override
public void componentResized(ComponentEvent arg0) {
    System.err.println("resize handler");
    resizeOkay = false;
}

Без изменения размера пользователя, приведенный выше код печатает:

No handler should be called between here
and here.
resize handler
resize handler

Как еще это называется?Это предотвращает изменение размеров окон.

Ответы [ 3 ]

2 голосов
/ 13 мая 2011

Как отличить изменение размера пользователя от программного изменения?

Для программного изменения размера код будет выглядеть примерно так:

panel.removeListeners(...);
doPanelResizing();
panel.addListeners();

То есть программа находится вконтроль того, что слушателя увольняют.

1 голос
/ 13 мая 2011

@ Нейт Гленн Используйте метод setResisable (), как подсказывает @StanislavL (+1). Это отключит изменение размера пользователя, в то время как вы все еще можете изменить размер программно Попробуйте сами, например. добавьте это main в ваш код и запустите его, увидев, что размер фрейма будет 200, 200, и вы не сможете изменить его размер.

    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {           
                JFrame f = new Grapher();
                f.setSize(400, 300);
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setResizable(false);
                f.setSize(200,200);
                f.setVisible(true);
            }
        });
    }

В противном случае, если ваша проблема на самом деле носит более конкретный характер, пожалуйста, попробуйте перефразировать ваш вопрос?

1 голос
/ 13 мая 2011
if (firstTime) {
  setResizable(false);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...