Java JScrollPane中的JEditorPane,带有修复背景图像

Java JScrollPane中的JEditorPane,带有修复背景图像,java,swing,background-image,jscrollpane,jeditorpane,Java,Swing,Background Image,Jscrollpane,Jeditorpane,我使用以下代码片段创建聊天日志 chatlog = new JEditorPane("text/html", "<html>") { private static final long serialVersionUID = 1L; protected void paintComponent(Graphics g) { // set background green - but can draw image here

我使用以下代码片段创建聊天日志

     chatlog = new JEditorPane("text/html", "<html>") {
        private static final long serialVersionUID = 1L;

        protected void paintComponent(Graphics g) {
            // set background green - but can draw image here too
            g.setColor(new Color(0,0,0,0));
            g.fillRect(0, 0, getWidth(), getHeight());

            // uncomment the following to draw an image
            Image img;
            try {
                img = ImageIO.read(new File("images/chatlog.png"));
                g.drawImage(img, 0, 0, this);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            super.paintComponent(g);
        }
    };

    chatlog.setFont(new Font("Segoe UI", Font.PLAIN, 14));
    chatlog.setEditable(false);
    chatlog.setOpaque(false);

    chatScroll = new JScrollPane(chatlog);
    chatScroll.setBounds(4, 454, 620, 100);
    chatScroll.setOpaque(false);
    chatScroll.setBackground(new Color(0,0,0,0));
    chatScroll.setBorder(BorderFactory.createEmptyBorder());
    chatScroll.setVisible(false);
chatlog=new-JEditorPane(“text/html”和“”){
私有静态最终长serialVersionUID=1L;
受保护组件(图形g){
//将背景设置为绿色-但也可以在此处绘制图像
g、 setColor(新颜色(0,0,0,0));
g、 fillRect(0,0,getWidth(),getHeight());
//取消注释以下内容以绘制图像
图像img;
试一试{
img=ImageIO.read(新文件(“images/chatlog.png”);
g、 drawImage(img,0,0,this);
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
超级组件(g);
}
};
setFont(新字体(“Segoe UI”,Font.PLAIN,14));
chatlog.setEditable(false);
setOpaque(false);
chatScroll=新的JScrollPane(聊天日志);
聊天卷轴.立根(4454620100);
chatcoll.setOpaque(false);
chatScroll.setBackground(新颜色(0,0,0,0));
setboorder(BorderFactory.createEmptyByOrder());
chatsroll.setVisible(false);
如你所见,我在“绝地武士”窗格中使用背景图像。但如果我在聊天日志中写入大量内容,背景图像会随着文本向上移动


你能帮我吗?

在标准HTML中,我们将使用
背景附件:滚动
CSS属性,当用户滚动页面时,强制BG向下滚动页面。黄色圆点放在样式中作为背景,以显示Swing如何不实现该属性

另一方面,宽-短黑色图像是由滚动窗格本身绘制的,因此出现在我们想要绘制它的任何地方

import java.awt.*;
导入java.awt.image.buffereImage;
导入javax.swing.*;
导入javax.swing.border.EmptyBorder;
TML中的公共类背景图像{
//用户看到的GUI(无框架)
私有JPanel gui;
私有最终静态字符串HTML=“”
+ ""
+ ""
+“正文{”
+“背景图像:http://i.stack.imgur.com/IHARa.png;"
+“背景重复:无重复;”
+“背景位置:左上;”
+“背景附件:滚动;”
+“颜色:#BBBBBB;”
+ "}"
+ ""
+ ""
+ ""
+“标题1”;
私有最终字符串段落="知识同我同我坐在一起,奉献给我们的精英们。我们不属于我们。我们坐在一起,是我们的门户。奎斯克·卢克图斯,我们的母亲,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭,我们的前庭“每一个祖先,每一个接受者,每一个智者,每一个非利奥人,每一个灵魂,每一个灵魂,每一个元素,每一个元素,每一个元素,每一个元素,每一个元素,每一个元素,每一个元素,每一个元素,每一个元素,每一个元素,每一个元素,每一个元素。”;
背景图像InHTML(){
初始化gui();
}
public void initializegui(){
gui=新的JPanel(newborderlayout());
setboorder(新的EmptyBorder(5,5,5,5));
//待办事项-不理想
setPreferredSize(新维度(400100));
StringBuilder sb=新的StringBuilder();
sb.append(HTML);
对于(int ii=0;ii<10;ii++){
sb.附加(“标题2”);
某人附加(段落);
}
JEditorPane jep=新的JEditorPane();
jep.setOpaque(假);
setContentType(“text/html”);
jep.setText(sb.toString());
JScrollPane jsp=新的JScrollPane(jep){
BuffereImage bg=新的BuffereImage(350,50,BuffereImage.TYPE_INT_RGB);
@凌驾
公共组件(图形g){
超级组件(g);
g、 drawImage(bg,0,0,this);
}
};
jsp.getViewport().setOpaque(false);
添加(jsp);
}
公共JComponent getGui(){
返回gui;
}
公共静态void main(字符串[]args){
Runnable r=新的Runnable(){
@凌驾
公开募捐{
BackgroundImageInHTML bih=新的BackgroundImageInHTML();
JFrame f=新JFrame(“演示”);
f、 添加(bih.getGui());
//确保JVM在帧关闭后关闭,并且
//所有非守护进程线程都已完成
f、 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
//看http://stackoverflow.com/a/7143398/418556 用于演示。
f、 setLocationByPlatform(真);
//确保框架为所需的最小尺寸
//以便显示其中的组件
f、 包装();
//应最后完成,以避免闪烁、移动,
//调整工件大小。
f、 setVisible(真);
}
};
//应在EDT上创建和更新Swing GUI
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency
SwingUtilities.invokeLater(r);
}
}

unrelated:永远不要手动调整组件的大小/位置-这是LayoutManager的专属责任。related:是的,在编辑器顶部绘制时还应该做什么:-)缩放以填充整个窗格(可能看起来有点奇怪)或将其绘制为视口的背景
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class BackgroundImageInHTML {

    // the GUI as seen by the user (without frame)
    private JPanel gui;
    private final static String HTML = "<html>"
            + "<head>"
            + "<style type=text/css>"
            + "body {"
            + "  background-image: http://i.stack.imgur.com/IHARa.png;"
            + "  background-repeat:no-repeat;"
            + "  background-position:left top;"
            + "  background-attachment: scroll;"
            + "  color: #BBBBBB;"
            + "}"
            + "</style>"
            + "</head>"
            + "<body>"
            + "<h1>Heading 1</h1>";
    private final String PARAGRAPH = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean eu nulla urna. Donec sit amet risus nisl, a porta enim. Quisque luctus, ligula eu scelerisque gravida, tellus quam vestibulum urna, ut aliquet sapien purus sed erat. Pellentesque consequat vehicula magna, eu aliquam magna interdum porttitor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Sed sollicitudin sapien non leo tempus lobortis. Morbi semper auctor ipsum, a semper quam elementum a. Aliquam eget sem metus.";

    BackgroundImageInHTML() {
        initializGui();
    }

    public void initializGui() {
        gui = new JPanel(new BorderLayout());
        gui.setBorder(new EmptyBorder(5, 5, 5, 5));
        // TODO - not ideal
        gui.setPreferredSize(new Dimension(400, 100));

        StringBuilder sb = new StringBuilder();
        sb.append(HTML);
        for (int ii = 0; ii < 10; ii++) {
            sb.append("<h2>Header 2</h2>");
            sb.append(PARAGRAPH);
        }
        JEditorPane jep = new JEditorPane();
        jep.setOpaque(false);
        jep.setContentType("text/html");
        jep.setText(sb.toString());
        JScrollPane jsp = new JScrollPane(jep) {
            BufferedImage bg = new BufferedImage(350,50,BufferedImage.TYPE_INT_RGB);
            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                g.drawImage(bg, 0, 0, this);
            }
        };
        jsp.getViewport().setOpaque(false);
        gui.add(jsp);
    }

    public JComponent getGui() {
        return gui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {

                BackgroundImageInHTML bih = new BackgroundImageInHTML();

                JFrame f = new JFrame("Demo");
                f.add(bih.getGui());
                // Ensures JVM closes after frame(s) closed and
                // all non-daemon threads are finished
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                // See http://stackoverflow.com/a/7143398/418556 for demo.
                f.setLocationByPlatform(true);

                // ensures the frame is the minimum size it needs to be
                // in order display the components within it
                f.pack();
                // should be done last, to avoid flickering, moving,
                // resizing artifacts.
                f.setVisible(true);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency
        SwingUtilities.invokeLater(r);
    }
}