При написании этого вопроса я смог найти способ заставить его вести себя так, как я хотел. Основываясь на this, я все еще задаю вопрос, поскольку другие люди могут столкнуться с подобными проблемами.Проблемы с размерами с JTabbedPane и фиксированным содержимым высоты
У меня есть следующие проблемы с размером JTabbedPane, используемого для контента, который растягивается горизонтально, но имеет фиксированную высоту. Оба варианта для setTabLayoutPolicy()
, похоже, изменяют высоту содержимого и не будут последовательно отображать его на его предпочтительной или минимальной высоте.
С умолчанию WRAP_TAB_LAYOUT
, предпочтительный размер вкладок панели не учитывает ли вкладки фактически сложенных или отображается рядом друг с другом в данный момент, как обсуждалось here, here и в this bug report. Если панель с вкладками выложена на основе уложенных вкладок, высота содержимого увеличивается примерно на 20 пикселей (высота одной вкладки) для каждой вкладки, добавленной, когда достаточно места для вкладок, которые будут отображаться рядом друг с другом. Если панель с вкладками выложена на основе вкладок, отображаемых рядом друг с другом, высота содержимого уменьшается, когда вкладки должны быть сложены.
Когда политика установлена в SCROLL_TAB_LAYOUT
, высота панели вкладок фиксирована, а макет в основном верен. Однако в зависимости от внешнего вида размер содержимого вкладки уменьшается на несколько пикселей. Я смог узнать, что это связано с вставками области табуляции, как определено L & F, которые не учитываются при вычислении предпочтительного размера панели вкладок (см. this bug report). Установка UIManager.getDefaults().put("TabbedPane.tabAreaInsets", new Insets(0,0,0,0))
работает для некоторых L & F (например, Metal), но не для других (например, Nimbus).
кажется, что есть только следующие варианты:
- использовать сложены вкладки и имеют дополнительную высоту добавлены к содержанию
- использовать сложены вкладки и имеют содержание охватывает, когда не хватает места
- используйте прокрученные вкладки и добавьте несколько пикселей к минимальному/предпочтительному размеру содержимого вкладки, что делает его немного отличающимся с каждым L & F (но, по крайней мере, содержимое не должно быть обрезано)
- использовать прокрученные вкладки и установить UI o е вкладки панель на новый
BasicTabbedPaneUI
который не выглядит большой
Есть чистый способ обеспечить, чтобы содержание вкладок панели всегда отображаются на фиксированную высоту для?
Следующий код и скриншоты иллюстрируют проблему
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.UIManager;
public class TabbedPaneTest extends JFrame {
TabbedPaneTest() {
JPanel mainPanel = new JPanel();
mainPanel.setBackground(Color.white);
JTabbedPane tabs = new JTabbedPane();
//tabs.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); // content cut off by a few pixels
tabs.setTabPlacement(JTabbedPane.BOTTOM);
Dimension min = new Dimension(100,200);
Dimension max = new Dimension(Short.MAX_VALUE,Short.MAX_VALUE);
//Dimension pref = new Dimension(Short.MAX_VALUE,200); // content cut off when small
Dimension pref = new Dimension(0,200); // content gets extra space when large
int tabCount = 3;
for (int i = 0; i < tabCount; i++) {
JLabel content = new JLabel();
content.setMinimumSize(min);
content.setMaximumSize(max);
content.setPreferredSize(pref);
tabs.addTab("lorem ipsum dolor sit amet", content);
}
// set up and render window
getContentPane().add(mainPanel, BorderLayout.CENTER);
getContentPane().add(tabs, BorderLayout.PAGE_END);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("JScrollPane Test");
pack();
setSize(700,400);
tabs.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
JTabbedPane tabbedPane = (JTabbedPane) e.getComponent();
int tabCount = tabbedPane.getTabCount();
for (int i = 0; i < tabCount; i++) {
Component c = tabbedPane.getComponentAt(i);
((JLabel) c).setText("<html>"
+ getSizes(c, "content")
+ getSizes(tabbedPane, "tabs")
+ "</html>");
}
}
});
}
private static String getSizes(Component c, String name) {
return "<p>" + name + " - "
+ " minimum:" + Integer.toString(c.getMinimumSize().width)
+ "x" + Integer.toString(c.getMinimumSize().height)
+ " maximum:" + Integer.toString(c.getMaximumSize().width)
+ "x" + Integer.toString(c.getMaximumSize().height)
+ " preferred:" + Integer.toString(c.getPreferredSize().width)
+ "x" + Integer.toString(c.getPreferredSize().height)
+ " actual:" + Integer.toString(c.getSize().width)
+ "x" + Integer.toString(c.getSize().height)
+ "</p>";
}
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(TabbedPaneTest.class
.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
@Override public void run() {
new TabbedPaneTest().setVisible(true);
}
});
}
}
С прокручивать вкладки, содержание отрезанный несколько пикселей (193px вместо 200px здесь):
Сложенными вкладками и широким контентом содержимое обрезается, когда окно мало (здесь 160px вместо 200px):
С СТекой закладками и узким содержанием, содержание сделано больше, когда окно является большим (240px вместо 200px здесь):