У меня есть родитель JPanel с 3 детьми JPanel внутри. Все они в настоящее время используют GridLayout и вместе представляют класс UML. Проблема в том, что когда я добавляю новый атрибут или метод, все 3 JPanel растут до одинакового размера.
Желание поведения таково:
- Размер поля заголовка всегда остается неизменным при добавлении метода или атрибута.
- При добавлении метода увеличивается только панель методов, а размер заголовка и панели атрибутов остается неизменным.
- При добавлении атрибута увеличивается только панель атрибутов, а размер других панелей остается прежним.
Родительский JPanel уже может автоматически увеличиваться / уменьшаться при добавлении метода / атрибута. Я играю с GridBagLayout atm, но я не приближаюсь к желаемым результатам.
Есть ли простой (или более простой) способ решить эту проблему?!
Вот несколько фотографий, чтобы показать мою ситуацию.
Недавно созданный класс UML =>
так он себя ведет в настоящее время => ![enter image description here](https://i.stack.imgur.com/d5hS7.png)
Но я хочу это =>
или это =>
или это => ![enter image description here](https://i.stack.imgur.com/IR1vr.png)
Edit2: добавлены новые картинки для наглядности. Мне ужасно жаль, если оригинальная версия вводила в заблуждение.
Edit3: ДА! Я разобрал это! Чувствовал как навсегда !! Вот SSEEC:
Детская панель
import java.awt.Component;
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.MouseInputAdapter;
import javax.swing.event.MouseInputListener;
public class APanel extends JPanel{
private JTextField tf;
public APanel() {
this.setLayout(new GridLayout(0,1));
this.addMouseListener(mouseInputListener);
}
MouseInputListener mouseInputListener = new MouseInputAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("Adding a new text field!");
tf = MyTF.create("Double click");
addNewTF(tf);
Component source = (Component) e.getSource();
Container c = source.getParent();
while(true) {
if(c instanceof PPanel)
break;
else
c=c.getParent();
}
PPanel p = (PPanel) c;
p.expand();
}
};
public void addNewTF(JTextField tf) {
this.add(tf);
this.setSize(this.getWidth(), this.getHeight()+tf.getHeight());
this.revalidate();
this.repaint();
}
}
Родительская панель:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
public class PPanel extends JPanel{
//private APanel panel1;
private JPanel panel1;
private APanel panel2;
private APanel panel3;
public PPanel() {
this.setLayout(new BoxLayout(this , BoxLayout.Y_AXIS));
this.setBackground(Color.black);
panel1 = new JPanel();
panel1.setLayout(new GridLayout(0,1));
panel1.add(new JTextField("title"));
panel2 = new APanel();
panel2.setBorder(BorderFactory.createLineBorder(Color.red));
panel3 = new APanel();
panel3.setBorder(BorderFactory.createLineBorder(Color.black));
this.add(panel1);
this.add(Box.createRigidArea(new Dimension(0,1)));
this.add(panel2);
this.add(panel3);
}
public void expand() {
this.setSize(this.getWidth(), this.getHeight()+33);
this.revalidate();
this.repaint();
}
public static void main(String[] args) {
JFrame frame = new JFrame();
PPanel panel = new PPanel();
panel.setBounds(10, 10, 100, 150);
JPanel c = new JPanel(null);
c.add(panel);
frame.add(c);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(350, 300));
frame.setTitle("Demo");
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Класс помощи:
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import javax.swing.JTextField;
import javax.swing.event.MouseInputAdapter;
import javax.swing.event.MouseInputListener;
public class MyTF {
public static JTextField create(String name) {
final JTextField tf = new JTextField(name);
System.out.println(tf.getPreferredSize());
tf.setPreferredSize(new Dimension(100,33));
tf.addMouseListener(mouseInputListener);
return tf;
}
static MouseInputListener mouseInputListener = new MouseInputAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
Component source = (Component) e.getSource();
Container c = source.getParent();
while(true) {
if(c instanceof PPanel)
break;
else if(c instanceof APanel)
{
c.dispatchEvent(e);
c = c.getParent();
break;
}
else
c=c.getParent();
}
c.dispatchEvent(e);
}
};
}
Я отказался от игры с GridBagLayout, это было слишком много для меня. Затем я попробовал borderLayout, как было предложено, но не смог заставить его работать так, как я хочу. Затем, наконец, BoxLayout, он должен был сработать, но в моем коде была ошибка! Поэтому, когда я попробовал 0бербозный код предложить и поиграть с ним, он потерпел неудачу! До тех пор, пока я не закончил SSEEC, не выполнил окончательную компиляцию и не запустил ее, прежде чем решил опубликовать (я практически сдался), затем я понял, что это работает не мешать друг другу.
Я был как WTF!
Вернулся к моему коду и сравнил его с SSEEC, и была ошибка, код для увеличения высоты панели был в неправильном месте, так что они как будто перебирали друг друга.
Еще лучше! Я могу указать расстояние между средней рамкой с рамкой над и под ней на один пиксель. Это означает, что я все еще могу использовать трюк от mKorbel, чтобы нарисовать черту, разделяющую эти ящики!
Редактировать 4: есть ли способ установить размер компонента? Если вы запустите SSEEC, вы заметите, что как только JTextField добавлен, он огромен! Это больше, чем контейнер ...