Java JTextPane垂直对齐

Java JTextPane垂直对齐,java,swing,jtextpane,Java,Swing,Jtextpane,我正在开发一个简单的文本冒险游戏,它应该允许用户输入文本并获得他们的响应,就像一个简单的命令提示符 出于各种原因,我尝试使用JPanel窗口和其他一些东西,以便控制内容的显示方式。下面是我到目前为止的代码 但是,我遇到了一些问题:JTextPane中的文本与窗口顶部对齐,而不是底部对齐,并且文本不可滚动。基本上,您刚刚输入的文本应该像命令提示符一样出现在文本输入框的上方,并且旧文本应该是可滚动的。有人知道我该怎么解决这个问题吗 提前谢谢 小编辑:这里有一个屏幕截图,它现在看起来像什么 用谷歌搜

我正在开发一个简单的文本冒险游戏,它应该允许用户输入文本并获得他们的响应,就像一个简单的命令提示符

出于各种原因,我尝试使用JPanel窗口和其他一些东西,以便控制内容的显示方式。下面是我到目前为止的代码

但是,我遇到了一些问题:JTextPane中的文本与窗口顶部对齐,而不是底部对齐,并且文本不可滚动。基本上,您刚刚输入的文本应该像命令提示符一样出现在文本输入框的上方,并且旧文本应该是可滚动的。有人知道我该怎么解决这个问题吗

提前谢谢

小编辑:这里有一个屏幕截图,它现在看起来像什么


用谷歌搜索你能找到的东西真是太棒了

因此,下面的示例基于。这个例子确实在视图的底部留下了一个“空白”行,我相信只要稍加努力,您就可以找到如何删除它,但这将为您提供一个起点

导入java.awt.BorderLayout;
导入java.awt.EventQueue;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.JTextPane;
导入javax.swing.UIManager;
导入javax.swing.UnsupportedLookAndFeelException;
导入javax.swing.text.AbstractDocument;
导入javax.swing.text.BadLocationException;
导入javax.swing.text.BoxView;
导入javax.swing.text.ComponentView;
导入javax.swing.text.Document;
导入javax.swing.text.Element;
导入javax.swing.text.IconView;
导入javax.swing.text.LabelView;
导入javax.swing.text.ParagraphView;
导入javax.swing.text.StyleConstants;
导入javax.swing.text.StyledEditorKit;
导入javax.swing.text.View;
导入javax.swing.text.ViewFactory;
公开课考试{
公共静态void main(字符串[]args){
新测试();
}
公开考试(){
invokeLater(新的Runnable(){
@凌驾
公开募捐{
试一试{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}catch(ClassNotFoundException |实例化Exception | IllegalacessException |不支持ookandfeelException ex){
例如printStackTrace();
}
JFrame=新JFrame(“测试”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(newtestpane());
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
}
});
}
公共类TestPane扩展了JPanel{
私有整数行数=0;
公共测试窗格(){
setLayout(新的BorderLayout());
JTextPane=新的JTextPane();
tp.setEditorKit(newmyeditorkit());
添加(新的JScrollPane(tp));
JButton btn=新JButton(“添加”);
btn.addActionListener(新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
试一试{
Document doc=tp.getDocument();
int end=doc.getLength();
doc.insertString(end,(++lineCount)+“更多文本”,null);
}捕获(BadLocationException ex){
例如printStackTrace();
}
}
});
添加(btn,BorderLayout.SOUTH);
}
}
类MyEditorKit扩展了StyledEditorKit{
公共ViewFactory getViewFactory(){
返回新的StyledViewFactory();
}
类StyledViewFactory实现ViewFactory{
公共视图创建(元素元素){
字符串种类=elem.getName();
如果(种类!=null){
if(kind.equals(AbstractDocument.ContentElementName)){
返回新的LabelView(elem);
}else if(kind.equals(AbstractDocument.ParagraphElementName)){
返回新段落视图(elem);
}else if(kind.equals(AbstractDocument.SectionElementName)){
返回新的CenteredBoxView(元素,视图Y_轴);
}else if(kind.equals(StyleConstants.ComponentElementName)){
返回新组件视图(elem);
}else if(kind.equals(StyleConstants.IconElementName)){
返回新的IconView(元素);
}
}
返回新的LabelView(elem);
}
}
}
以类为中心的BoxView扩展了BoxView{
公共中心框视图(元素元素,内轴){
超级(元素,轴);
}
受保护的空心布局主轴线(int targetSpan、int轴、int[]偏移量、int[]跨距){
超级布局主轴线(目标跨度、轴、偏移、跨度);
int textBlockHeight=0;
整数偏移=0;
对于(int i=0;i

奇妙之处在于
layoutmayoraxis
方法

通过谷歌搜索,你会发现惊人的发现

因此,下面的示例基于。这个例子确实在视图的底部留下了一个“空白”行,我相信只要稍加努力,您就可以找到如何删除它,但这将为您提供一个起点

导入java.awt.BorderLayout;
导入java.awt.EventQueue;
导入java.awt.event.ActionEvent;
导入java.awt.event。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

public class TextDemo extends JPanel implements ActionListener {

protected JTextField textField;
protected JTextPane textArea;
private final static String newline = "\n";
public static Color fg = Color.WHITE, bg = Color.BLACK;
public static final Font header = new Font("Times New Roman", Font.PLAIN, 96);
public static final Font normal = new Font("Times New Roman", Font.PLAIN, 24);

public TextDemo() {
    super(new GridBagLayout());

    textField = new JTextField();
    textField.setFont(normal);
    textField.setForeground(fg);
    textField.setBackground(bg);
    textField.setPreferredSize(new Dimension(640, 30));
    textField.addActionListener(this);

    textArea = new JTextPane();
    textArea.setFont(normal);

    //textArea.setLineWrap(true);
    //textArea.setWrapStyleWord(true);
    textArea.setForeground(fg);
    textArea.setBackground(bg);
    textArea.setPreferredSize(new Dimension(640, 450));
    textArea.setEditable(false);
    //textArea.setAlignmentY(Component.BOTTOM_ALIGNMENT);


    JScrollPane scrollPane = new JScrollPane(textArea);

    //scrollPane.setAlignmentY(JScrollPane.BOTTOM_ALIGNMENT);
    //Add Components to this panel.
    GridBagConstraints c = new GridBagConstraints();
    c.gridwidth = GridBagConstraints.REMAINDER;

    c.fill = GridBagConstraints.BOTH;`

    c.weightx = 1.0;
    c.weighty = 1.0;
    add(scrollPane, c);

    c.fill = GridBagConstraints.HORIZONTAL;
    add(textField, c);

    //add(textArea, BorderLayout.SOUTH);
}

public void actionPerformed(ActionEvent evt) {
    SimpleAttributeSet sas = new SimpleAttributeSet();
    StyleConstants.setAlignment(sas, StyleConstants.ALIGN_RIGHT);
    StyleConstants.setForeground(sas, Color.WHITE);
    String text = textField.getText();
    Document doc = textArea.getStyledDocument();
    try {
        doc.insertString(doc.getLength(), text + newline, sas);
    } catch (BadLocationException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    //textArea.append(text + newline);
    textField.setText("");

}

private static void createAndShowGUI() {
    //Create and set up the window.
    JFrame frame = new JFrame("TextDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    //Add contents to the window.
    frame.add(new TextDemo());

    //Display the window.
    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {
    TextDemo.createAndShowGUI();
}
}
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.AbstractDocument;
import javax.swing.text.BadLocationException;
import javax.swing.text.BoxView;
import javax.swing.text.ComponentView;
import javax.swing.text.Document;
import javax.swing.text.Element;
import javax.swing.text.IconView;
import javax.swing.text.LabelView;
import javax.swing.text.ParagraphView;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.View;
import javax.swing.text.ViewFactory;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private int lineCount = 0;

        public TestPane() {
            setLayout(new BorderLayout());
            JTextPane tp = new JTextPane();
            tp.setEditorKit(new MyEditorKit());
            add(new JScrollPane(tp));

            JButton btn = new JButton("Add");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    try {
                        Document doc = tp.getDocument();
                        int end = doc.getLength();
                        doc.insertString(end, (++lineCount) + " some more text\n", null);
                    } catch (BadLocationException ex) {
                        ex.printStackTrace();
                    }
                }
            });

            add(btn, BorderLayout.SOUTH);
        }

    }

    class MyEditorKit extends StyledEditorKit {

        public ViewFactory getViewFactory() {
            return new StyledViewFactory();
        }

        class StyledViewFactory implements ViewFactory {

            public View create(Element elem) {
                String kind = elem.getName();
                if (kind != null) {
                    if (kind.equals(AbstractDocument.ContentElementName)) {

                        return new LabelView(elem);
                    } else if (kind.equals(AbstractDocument.ParagraphElementName)) {
                        return new ParagraphView(elem);
                    } else if (kind.equals(AbstractDocument.SectionElementName)) {

                        return new CenteredBoxView(elem, View.Y_AXIS);
                    } else if (kind.equals(StyleConstants.ComponentElementName)) {
                        return new ComponentView(elem);
                    } else if (kind.equals(StyleConstants.IconElementName)) {

                        return new IconView(elem);
                    }
                }

                return new LabelView(elem);
            }

        }
    }

    class CenteredBoxView extends BoxView {

        public CenteredBoxView(Element elem, int axis) {

            super(elem, axis);
        }

        protected void layoutMajorAxis(int targetSpan, int axis, int[] offsets, int[] spans) {

            super.layoutMajorAxis(targetSpan, axis, offsets, spans);
            int textBlockHeight = 0;
            int offset = 0;

            for (int i = 0; i < spans.length; i++) {

                textBlockHeight += spans[i];
            }
            offset = targetSpan - textBlockHeight;
            for (int i = 0; i < offsets.length; i++) {
                offsets[i] += offset;
            }

        }
    }
}