Как мне это сделать?
Вот демо . Я ответил на некоторые критические замечания по поводу моих предыдущих вопросов об использовании внешних библиотек, поэтому здесь они не используются
Код: Выделить всё
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.Objects;
public class FlowToolbarDemo {
public static void main(String[] args) throws IOException {
JFrame frame = new JFrame("Flow Toolbar Demo");
JPanel labelPanel = new JPanel(new BorderLayout());
JLabel label = new JLabel("Click to see action");
label.setOpaque(true);
label.setBackground(new Color(255, 255, 204));
labelPanel.add(label, BorderLayout.CENTER);
JToolBar toolbar = new JToolBar();
LayoutManager toolbarLayout = new FlowLayout();
toolbar.setLayout(toolbarLayout);
JButton heartButton = getHeartButton(e -> label.setText("Heart action performed..."));
JButton starButton = getStarButton(e -> label.setText("Star action performed..."));
toolbar.add(heartButton);
toolbar.add(starButton);
LayoutManager headerPanelLayout = new BorderLayout();
JPanel headerPanel = new JPanel(headerPanelLayout);
headerPanel.add(labelPanel, BorderLayout.NORTH);
headerPanel.add(toolbar, BorderLayout.CENTER);
JPanel businessPanel = getBusinessPanel();
LayoutManager mainPanelLayout = new BorderLayout();
JPanel mainPanel = new JPanel(mainPanelLayout);
mainPanel.add(headerPanel, BorderLayout.NORTH);
mainPanel.add(businessPanel, BorderLayout.CENTER);
frame.setContentPane(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setVisible(true);
System.out.println();
}
private static JPanel getBusinessPanel() {
LayoutManager businessPanelLayout = new BorderLayout();
JPanel businessPanel = new JPanel(businessPanelLayout);
JTable tableOne = getTableOne();
JScrollPane scrollPaneOne = new JScrollPane(tableOne);
scrollPaneOne.setOpaque(true);
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("Business Table One", scrollPaneOne);
JTable tableTwo = getTableTwo();
JScrollPane scrollPaneTwo = new JScrollPane(tableTwo);
scrollPaneTwo.setOpaque(true);
tabbedPane.addTab("Business Table Two", scrollPaneTwo);
businessPanel.add(tabbedPane);
return businessPanel;
}
private static JTable getTableOne() {
Object[][] data = {
{"John Doe", 30, "Male"},
{"Jane Smith", 25, "Female"},
{"Alice Johnson", 35, "Female"}
};
String[] columns = {"Name", "Age", "Gender"};
DefaultTableModel model = new DefaultTableModel(data, columns);
return new JTable(model);
}
private static JTable getTableTwo() {
Object[][] data = {
{"Apple", 30, true},
{"Orange", 25, true},
{"Ackee fruit", 35, false}
};
String[] columns = {"Fruit", "Quantity", "Is Edible"};
DefaultTableModel model = new DefaultTableModel(data, columns);
return new JTable(model);
}
private static JButton getHeartButton(ActionListener heartAction) throws IOException {
return getButton("Do Heart action", "heart.png", heartAction);
}
private static JButton getStarButton(ActionListener starAction) throws IOException {
return getButton("Do Star action", "star.png", starAction);
}
private static JButton getButton(String buttonText, String resourceName, ActionListener actionListener) throws IOException {
URL imageLocation = FlowToolbarDemo.class.getResource(resourceName);
BufferedImage image = ImageIO.read(Objects.requireNonNull(imageLocation, "Requested resource not found"));
Image scaledImage = image.getScaledInstance(20, 20, Image.SCALE_SMOOTH);
ImageIcon icon = new ImageIcon(scaledImage);
JButton button = new JButton(buttonText, icon);
button.addActionListener(actionListener);
button.setFocusPainted(false);
return button;
}
}
Код: Выделить всё
heart.png
Код: Выделить всё
star.png
Кнопки перемещаются, но они располагаются ниже выделенной области для северного компонента и становятся практически невидимыми. С другой стороны, заголовки панелей JTabbedPane плавно перетекают. Я включил его частично, чтобы показать, какого типа «плавности» я пытаюсь добиться с помощью кнопок на панели инструментов.
[img]https:/ /i.sstatic.net/gYUheBPI.png[/img]

Код: Выделить всё
BorderLayout
Технически это достижимо с помощью такого уродливого ключа
Код: Выделить всё
toolbar.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
Component firstButton = toolbar.getComponent(0);
double firstButtonY = firstButton.getLocation().getY();
Component secondButton = toolbar.getComponent(1);
double secondButtonY = secondButton.getLocation().getY();
if (firstButtonY < secondButtonY) {
int newHeight = (int) ((firstButton.getHeight() + secondButton.getHeight()) * 1.25);
toolbar.setPreferredSize(new Dimension(toolbar.getPreferredSize().width, newHeight));
} else if (firstButtonY == firstButtonY) {
int oldHeight = (int) (firstButton.getHeight() * 1.25);
toolbar.setPreferredSize(new Dimension(toolbar.getPreferredSize().width, oldHeight));
}
}
});
Даже если несколько улучшить его, заменив жестко закодированные множители на средства доступа vGap
p>
Код: Выделить всё
toolbar.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
FlowLayout flowLayout = (FlowLayout) toolbar.getLayout();
JButton firstButton = (JButton) toolbar.getComponent(0);
JButton secondButton = (JButton) toolbar.getComponent(1);
double firstButtonY = firstButton.getLocation().getY();
double secondButtonY = secondButton.getLocation().getY();
if (firstButtonY < secondButtonY) {
int newHeight = firstButton.getHeight() + secondButton.getHeight() + flowLayout.getVgap() * 3;
toolbar.setPreferredSize(new Dimension(toolbar.getPreferredSize().width, newHeight));
} else if (firstButtonY == firstButtonY) {
int oldHeight = firstButton.getHeight() + flowLayout.getVgap() * 2;
toolbar.setPreferredSize(new Dimension(toolbar.getPreferredSize().width, oldHeight));
}
}
});
Подробнее здесь: https://stackoverflow.com/questions/787 ... g-jtoolbar