powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Проблема с обновлением JPanel
8 сообщений из 8, страница 1 из 1
Проблема с обновлением JPanel
    #38888398
Slavuti4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть небольшая программа - по клику на JPanel на нее добавляются кнопки заданного размера и отображается количество уже добавленных кнопок.
Класс MainFrame - код основного окна, сделанный с помощью JFormDesigner

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;

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


public class MainFrame {

	JFrame mainFrame;
	private JPanel topPanel;
	private JPanel paramPanel;
	private JLabel label1;
	JSpinner wSpinner;
	private JLabel label2;
	JSpinner hSpinner;
	JPanel resultPanel;
	JLabel resultLabel;
	JPanel centerPanel;
	int count = 0;


	public void initComponents() {
		// JFormDesigner - Component initialization - DO NOT MODIFY  //GEN-BEGIN:initComponents
		// Generated using JFormDesigner Evaluation license - sd sdsd
		mainFrame = new JFrame();
		topPanel = new JPanel();
		paramPanel = new JPanel();
		label1 = new JLabel();
		wSpinner = new JSpinner();
		label2 = new JLabel();
		hSpinner = new JSpinner();
		resultPanel = new JPanel();
		resultLabel = new JLabel();
		centerPanel = new JPanel();


		wSpinner.setValue( 50 );
		hSpinner.setValue( 50 );

		//======== mainFrame ========
		{
			mainFrame.setMinimumSize( new Dimension( 300, 300 ) );
			Container mainFrameContentPane = mainFrame.getContentPane();
			mainFrameContentPane.setLayout( new BorderLayout() );

			//======== topPanel ========
			{

				topPanel.setLayout( new GridLayoutManager( 2, 2, new Insets( 0, 0, 0, 0 ), 0, 0 ) );

				//======== paramPanel ========
				{
					paramPanel.setLayout( new GridLayoutManager( 2, 2, new Insets( 0, 0, 0, 0 ), -1, -1 ) );

					//---- label1 ----
					label1.setText( "Ширина" );
					paramPanel.add( label1, new GridConstraints( 0, 0, 1, 1, GridConstraints.ANCHOR_CENTER,
																 GridConstraints.FILL_NONE,
																 GridConstraints.SIZEPOLICY_CAN_SHRINK |
																 GridConstraints.SIZEPOLICY_CAN_GROW,
																 GridConstraints.SIZEPOLICY_CAN_SHRINK |
																 GridConstraints.SIZEPOLICY_CAN_GROW, null, null,
																 null ) );

					paramPanel.add( wSpinner, new GridConstraints( 0, 1, 1, 1, GridConstraints.ANCHOR_CENTER,
																   GridConstraints.FILL_NONE,
																   GridConstraints.SIZEPOLICY_CAN_SHRINK |
																   GridConstraints.SIZEPOLICY_CAN_GROW,
																   GridConstraints.SIZEPOLICY_CAN_SHRINK |
																   GridConstraints.SIZEPOLICY_CAN_GROW, null, null,
																   null ) );

					//---- label2 ----
					label2.setText( "Высота" );
					paramPanel.add( label2, new GridConstraints( 1, 0, 1, 1, GridConstraints.ANCHOR_CENTER,
																 GridConstraints.FILL_NONE,
																 GridConstraints.SIZEPOLICY_CAN_SHRINK |
																 GridConstraints.SIZEPOLICY_CAN_GROW,
																 GridConstraints.SIZEPOLICY_CAN_SHRINK |
																 GridConstraints.SIZEPOLICY_CAN_GROW, null, null,
																 null ) );
					paramPanel.add( hSpinner, new GridConstraints( 1, 1, 1, 1, GridConstraints.ANCHOR_CENTER,
																   GridConstraints.FILL_NONE,
																   GridConstraints.SIZEPOLICY_CAN_SHRINK |
																   GridConstraints.SIZEPOLICY_CAN_GROW,
																   GridConstraints.SIZEPOLICY_CAN_SHRINK |
																   GridConstraints.SIZEPOLICY_CAN_GROW, null, null,
																   null ) );
				}
				topPanel.add( paramPanel,
							  new GridConstraints( 0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints
									  .FILL_NONE,
												   GridConstraints.SIZEPOLICY_CAN_SHRINK |
												   GridConstraints.SIZEPOLICY_CAN_GROW,
												   GridConstraints.SIZEPOLICY_CAN_SHRINK |
												   GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null ) );

				//======== resultPanel ========
				{
					resultPanel.setLayout( new GridLayoutManager( 2, 2, new Insets( 0, 0, 0, 0 ), -1, -1 ) );

					//---- resultLabel ----
					resultLabel.setText( "text" );
					resultPanel.add( resultLabel, new GridConstraints( 0, 0, 1, 1, GridConstraints.ANCHOR_CENTER,
																	   GridConstraints.FILL_NONE,
																	   GridConstraints.SIZEPOLICY_CAN_SHRINK |
																	   GridConstraints.SIZEPOLICY_CAN_GROW,
																	   GridConstraints.SIZEPOLICY_CAN_SHRINK |
																	   GridConstraints.SIZEPOLICY_CAN_GROW, null, null,
																	   null ) );
				}
				topPanel.add( resultPanel,
							  new GridConstraints( 0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints
									  .FILL_NONE,
												   GridConstraints.SIZEPOLICY_CAN_SHRINK |
												   GridConstraints.SIZEPOLICY_CAN_GROW,
												   GridConstraints.SIZEPOLICY_CAN_SHRINK |
												   GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null ) );
			}
			mainFrameContentPane.add( topPanel, BorderLayout.NORTH );

			//======== centerPanel ========
			{
				centerPanel.setBackground( Color.white );
				centerPanel.setMinimumSize( new Dimension( 300, 300 ) );
				centerPanel.addMouseListener( new MouseListener( this ) );
			}
			mainFrameContentPane.add( centerPanel, BorderLayout.CENTER );
			mainFrame.pack();
			mainFrame.setLocationRelativeTo( mainFrame.getOwner() );
			mainFrame.setVisible( true );
			mainFrame.setDefaultCloseOperation( WindowConstants.EXIT_ON_CLOSE );
		}
		// JFormDesigner - End of component initialization  //GEN-END:initComponents
	}

	void updateCount() {
		count++;
		//resultLabel.setText( String.valueOf( count ) );
		
	}

	public static void main( String[] args ) {
		new MainFrame().initComponents();
	}

}



И класс MouseListener:
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import static java.awt.event.MouseEvent.BUTTON1;
import static java.awt.event.MouseEvent.BUTTON3;

public class MouseListener extends MouseAdapter {

	private MainFrame frame;

	public MouseListener( MainFrame mainFrame ) {
		this.frame = mainFrame;
	}

	@Override
	public void mouseClicked( MouseEvent e ) {
		if( e.getButton() == BUTTON1 || e.getButton() == BUTTON3 ) {
			JButton button = new JButton();
			button.setBounds( getBounds( e, frame ) );

			frame.centerPanel.add( button );
			frame.updateCount();
			frame.mainFrame.repaint();

		}
	}

	Rectangle getBounds( MouseEvent e, MainFrame frame ) {
		int w = Integer.parseInt( frame.wSpinner.getValue().toString() );
		int h = Integer.parseInt( frame.hSpinner.getValue().toString() );
		int x = e.getX();
		int y = e.getY();
		System.out.println( "added " + x + " " + y + " " + h + " " + w );
		return new Rectangle( x, y, w, h );
	}
}



Проблема вот в чем - если в методе updateCount() изменить надпись на JLabel с помощью setText, происходит следующее:

Если же закомментировать этот момент, то все в порядке:

Тоже самое происходит, если изменить вручную размеры окна.
Изучив гугл, пришел к выводу, что это происходит из-за метода updateUI(), который, видимо, вызывается автоматически. Если его вызвать вручную - проблема повторяется.
Подскажите, в какую сторону вообще копать? Виноват компоновщик или еще что-то?
И сразу второй вопрос - при добавлении этих самых кнопок по клику заметил, что событие не всегда срабатывает - если кликать быстро, то вообще ничего не добавляется. Если убрать repaint() - задержка вообще почти всегда. С чем это связано?
Заранее спасибо за любое объяснение\статьи и прочее :)
...
Рейтинг: 0 / 0
Проблема с обновлением JPanel
    #38888431
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: java
1.
centerPanel.setLayout(null);

Это необходимо для ручного позиционирования. Так как по-умолчанию используется FlowLayout. Из-за этого все проблемы. Потому что Layout manager не использует те Bounds что вы устанавливаете. Он используется PreferredSize. А Bounds устанавливает сам.

Забудьте про repaint() и updateUI(). Это рудименты, в которые новички постоянно утыкаются при борьбе с layout manager.
updateUI() относится к LookAndFeel. Класс отвечающий за отрисовку контрола в LAF имеет суффикс UI. Вот updateUI обновляет этот объект отрисовки привязанный к контролу.
repaint() не помню что именно там делает, но тоже не предназначен для ручного вызова из кода.
...
Рейтинг: 0 / 0
Проблема с обновлением JPanel
    #38888862
Slavuti4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz, огромное спасибо! А что по поводу лагов GUI? Это все Swing & потоки, в этом направлении разбираться?
...
Рейтинг: 0 / 0
Проблема с обновлением JPanel
    #38888901
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Slavuti4Blazkowicz, огромное спасибо! А что по поводу лагов GUI? Это все Swing & потоки, в этом направлении разбираться?
В чем конкретно лаги? Если updateUI и repaint убрать то и лагов не должно быть.
...
Рейтинг: 0 / 0
Проблема с обновлением JPanel
    #38888913
Slavuti4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz, когда быстро щелкаешь ЛКМ/ПКМ - кнопка не добавляется, либо вместо 2-3 добавляется всего 1. Даже в консоли пишет, что кнопка добавилась (отработал слушатель), цифра через setText изменилась, а кнопки нет. Либо кнопка добавляется с заметным запаздыванием. При быстрых кликах вообще ничего не происходит
...
Рейтинг: 0 / 0
Проблема с обновлением JPanel
    #38889129
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Slavuti4Blazkowicz, когда быстро щелкаешь ЛКМ/ПКМ - кнопка не добавляется, либо вместо 2-3 добавляется всего 1. Даже в консоли пишет, что кнопка добавилась (отработал слушатель), цифра через setText изменилась, а кнопки нет. Либо кнопка добавляется с заметным запаздыванием. При быстрых кликах вообще ничего не происходит
Много быстрых нажатий система воспринимает как double и даже triple click. MouseEvent.getClickCount().

Хочу так же отметить, что Swing это фреймверк для создания GUI. Делать на него основе какую-то "игру" это использовать его не по назначению. Конечно, будет намного быстрее если выкинуть контролы и вместо них реализовать свою модель с прямым отображением в Java2D.

Ещё достаточно странно что для вашей задачи вы выбрали Swing, а не JavaFX.
...
Рейтинг: 0 / 0
Проблема с обновлением JPanel
    #38889348
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А есть у кого-то образец JavaFX проекта с гридами?
...
Рейтинг: 0 / 0
Проблема с обновлением JPanel
    #38889371
Slavuti4
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz, большое спасибо, проблема решилась заменой mouseClicked() на mousePressed(). Swing использую просто для того, чтобы детально разобраться, как все работает, потом переделаю на чем-нибудь более современном :)
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Java [игнор отключен] [закрыт для гостей] / Проблема с обновлением JPanel
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]