我正在创建一个控制台,并且需要在JTextArea
内的JPanel
内有两个JScrollPane
。由于setLineWrap(true)
不直接位于JScrollPane
内,因此BorderLayout.CENTER
无效,我找到了一个简洁的解决方法here。这允许LineWrap属性工作,但遗憾地打破了其中一个JTextArea
的{{1}}属性。所以现在第二个JTextArea
将不会填满整个窗格。
以下是控制台的精简代码:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Rectangle;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Console2Fix extends JPanel{
public final String def_text;
private final Font font = new Font("Source Code Pro", Font.PLAIN, 12);
public JTextArea outPane, inPane;
private JScrollPane conScroll;
private ScrollablePanel scrollPanel;
public Console2Fix(String title){
super();
def_text = title + "";
//UI
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException e) {
System.out.println("catdch 1");
} catch (InstantiationException e1) {
System.out.println("catdch 2");
} catch (IllegalAccessException e1) {
System.out.println("catdch 3");
} catch (UnsupportedLookAndFeelException e1) {
System.out.println("catdch 4");
}
SwingUtilities.updateComponentTreeUI(this);
setLayout(new BorderLayout(0, 0));
//Output Area
outPane = new JTextArea();
outPane.setLineWrap(true);
outPane.setWrapStyleWord(true);
outPane.setBackground(new Color(40,40,40));
outPane.setForeground(Color.LIGHT_GRAY);
outPane.setFont(font);
outPane.setEditable(false);
//Input Area
inPane = new JTextArea();
inPane.setLineWrap(true);
inPane.setWrapStyleWord(true);
inPane.setBackground(new Color(42,42,42));
inPane.setForeground(Color.WHITE);
inPane.setFont(font);
inPane.setCaretColor(Color.WHITE);
//Modified JPanel to support Linewraping
scrollPanel = new ScrollablePanel();
scrollPanel.setLayout(new BorderLayout(0, 0));
scrollPanel.add(outPane, BorderLayout.NORTH);
scrollPanel.add(inPane, BorderLayout.CENTER);
//ScrollPane
conScroll = new JScrollPane(scrollPanel);
conScroll.setBorder(BorderFactory.createEmptyBorder());
conScroll.getHorizontalScrollBar().setPreferredSize(new Dimension(0, 13));
conScroll.getVerticalScrollBar().setPreferredSize(new Dimension(13, 0));
conScroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
this.add(conScroll, BorderLayout.CENTER);
outPane.setText(def_text);
createWindow();
}
//Creates JFrame for demonstration
public void createWindow() {
JFrame frame = new JFrame(def_text);
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(this);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
//Bonus question: How can I get this to work?
//- When this is called it should scroll the conScroll to the bottom
public void down(){
inPane.scrollRectToVisible(new Rectangle(inPane.getSize()));
}
public static void main(String[] args){
new Console2Fix("Console2Fix");
}
}
这是修改后的JPanel:
import java.awt.Dimension;
import java.awt.Rectangle;
import javax.swing.JPanel;
import javax.swing.Scrollable;
public class ScrollablePanel extends JPanel implements Scrollable{
public Dimension getPreferredScrollableViewportSize() {
return super.getPreferredSize(); //tell the JScrollPane that we want to be our 'preferredSize' - but later, we'll say that vertically, it should scroll.
}
public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
return 16;//set to 16 because that's what you had in your code.
}
public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
return 16;//set to 16 because that's what you had set in your code.
}
public boolean getScrollableTracksViewportWidth() {
return true;//track the width, and re-size as needed.
}
public boolean getScrollableTracksViewportHeight() {
return false; //we don't want to track the height, because we want to scroll vertically.
}
}
PS:我知道将getScrollableTracksViewportHeight()
更改为true
似乎可以解决问题,但实际上它会破坏VerticalScrollBar ......
提前感谢您的时间。