JScrollPane里面的JPanel里面的JTextArea

时间:2015-08-14 11:07:58

标签: java swing jpanel jscrollpane jtextarea

我正在创建一个控制台,并且需要在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 ......

PSPS:我刚刚注意到它在真正快速滚动时表现得很奇怪。好像它需要一个重绘()某处...

提前感谢您的时间。

0 个答案:

没有答案