Java 我想要一张图片在滚动时留在jscrollpane的左上角
我在JScrollpane中有一个JPanel。 我绘制了一个BuffereImage,显示在JPanel上。 在JScrollpane的左上角,我想要一张图片,当我向下滚动查看我的JPanel的其余部分时,它总是停留在那个角落。 以下是Jpanel的paintComponent方法:Java 我想要一张图片在滚动时留在jscrollpane的左上角,java,swing,jscrollpane,imageicon,jviewport,Java,Swing,Jscrollpane,Imageicon,Jviewport,我在JScrollpane中有一个JPanel。 我绘制了一个BuffereImage,显示在JPanel上。 在JScrollpane的左上角,我想要一张图片,当我向下滚动查看我的JPanel的其余部分时,它总是停留在那个角落。 以下是Jpanel的paintComponent方法: @Override public void paintComponent(Graphics g){ super.paintComponent(g); if (bufferedImage != nu
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
if (bufferedImage != null){
g.drawImage(bufferedImage, 0, 0, this);
Point p = parent.getViewPosition();
System.out.println("paintComponent(): "+ p.x + "," + p.y);
g.setColor(Color.RED);
g.fillRect(p.x + 20, p.y + 20, 200, 200);
}
}
其中parent.getViewPosition()为我提供滚动窗格.getViewport().getViewPosition()。
当我启动时,我可以看到在左上角有红色矩形的缓冲图像。
当我向下滚动时,我可以看到缓冲图像的其余部分,但红色矩形向上移动,然后消失,当我向上滚动时不再出现。
在控制台中,我可以看到点p在滚动时发生变化:
paintComponent(): 0,0
paintComponent(): 0,10
paintComponent(): 0,20
paintComponent(): 0,30
paintComponent(): 0,40
paintComponent(): 0,50
有人能帮我解决这个问题吗?不要把图片放在滚动的面板上。将其放在不同的面板中,并使用布局管理器排列这两个面板
我建议看看边界布局;它在n、s、e和w处有区域,在中心有一个区域,但不必全部使用(很少全部使用)。您可以创建一个JPanel,将其布局管理器设置为BorderLayout,将包含图像的面板放在该面板的北部,并将滚动面板放在中间。作为一种无成本奖励,当/如果调整窗口的大小,您位于中心的JPanel将在两个维度上拉伸,因为这就是BorderLayout的工作方式。您可以使用玻璃窗格进行此操作,并告诉它在视区位置而定的位置绘制图像。例如:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import javax.swing.*;
@SuppressWarnings("serial")
public class ScrollImgGlass extends JPanel {
private static final int BI_W = 40;
private static final int BI_H = BI_W;
private static final String[] DATA = { "One", "Two", "Three", "Four",
"Five", "Six", "Seven", "Eight", "Nine", "Zero", "One", "Two",
"Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Zero",
"One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight",
"Nine", "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven",
"Eight", "Nine", "Zero" };
private BufferedImage img = null;
private JViewport viewport;
public ScrollImgGlass(JViewport viewport) {
setOpaque(false);
this.viewport = viewport;
img = new BufferedImage(BI_W, BI_H, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setColor(Color.red);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.fillOval(0, 0, BI_W, BI_H);
g2.dispose();
}
@Override
protected void paintComponent(Graphics g) {
Point vpLocation = viewport.getLocationOnScreen();
Point gpLocation = getLocationOnScreen();
int x = vpLocation.x - gpLocation.x;
int y = vpLocation.y - gpLocation.y;
super.paintComponent(g);
if (img != null) {
g.drawImage(img, x, y, this);
}
}
private static void createAndShowGui() {
JList<String> jList = new JList<String>(DATA);
jList.setOpaque(false);
JViewport viewport = new JViewport();
JScrollPane scrollpane = new JScrollPane();
scrollpane.setViewport(viewport);
viewport.setView(jList);
ScrollImgGlass glass = new ScrollImgGlass(viewport);
JFrame frame = new JFrame("ScrollImg");
frame.setGlassPane(glass);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(scrollpane, BorderLayout.CENTER);
// just to show that this works if the viewport is shifted over
frame.getContentPane().add(Box.createRigidArea(new Dimension(20, 20)), BorderLayout.NORTH);
frame.getContentPane().add(Box.createRigidArea(new Dimension(20, 20)), BorderLayout.WEST);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
glass.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
导入java.awt.BorderLayout;
导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.Graphics2D;
导入java.awt.Point;
导入java.awt.RenderingHints;
导入java.awt.image.buffereImage;
导入javax.swing.*;
@抑制警告(“串行”)
公共类Scrollimglass扩展了JPanel{
专用静态最终int BI_W=40;
私有静态final int BI_H=BI_W;
私有静态最终字符串[]数据={“一”、“二”、“三”、“四”,
“五”、“六”、“七”、“八”、“九”、“零”、“一”、“二”,
“三”、“四”、“五”、“六”、“七”、“八”、“九”、“零”,
“一”、“二”、“三”、“四”、“五”、“六”、“七”、“八”,
“九”、“零”、“一”、“二”、“三”、“四”、“五”、“六”、“七”,
“八”、“九”、“零”};
私有缓冲区映像img=null;
私有视口;
公共ScrollImgClass(JViewport视口){
设置不透明(假);
this.viewport=视口;
img=新的BuffereImage(BI_W,BI_H,BuffereImage.TYPE_INT_ARGB);
Graphics2D g2=img.createGraphics();
g2.设置颜色(颜色为红色);
g2.setRenderingHint(RenderingHints.KEY_抗锯齿,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.椭圆形(0,0,BI_W,BI_H);
g2.dispose();
}
@凌驾
受保护组件(图形g){
Point vpLocation=viewport.getLocationOnScreen();
点gpLocation=getLocationOnScreen();
intx=vpLocation.x-gpLocation.x;
int y=vpLocation.y-gpLocation.y;
超级组件(g);
如果(img!=null){
g、 绘图图像(img,x,y,this);
}
}
私有静态void createAndShowGui(){
JList JList=新JList(数据);
jList.set不透明(假);
JViewport viewport=新的JViewport();
JScrollPane scrollpane=新的JScrollPane();
scrollpane.setViewport(视口);
viewport.setView(jList);
ScrollImgClass玻璃=新的ScrollImgClass(视口);
JFrame=新的JFrame(“ScrollImg”);
框架。玻璃板(玻璃);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(滚动窗格,BorderLayout.CENTER);
//只是为了说明如果视口被移到另一个位置,这种方法是有效的
frame.getContentPane().add(Box.createRigidArea(新维度(20,20)),BorderLayout.NORTH);
frame.getContentPane().add(Box.createRigidArea(新维度(20,20)),BorderLayout.WEST);
frame.pack();
frame.setLocationByPlatform(真);
frame.setVisible(true);
玻璃。设置可见(真实);
}
公共静态void main(字符串[]args){
SwingUtilities.invokeLater(新的Runnable(){
公开募捐{
createAndShowGui();
}
});
}
}
显示的内容如下:
您可以在代码中的某个地方创建一个JScrollPane 改变
final JScrollPane scrollpane = new JScrollPane();
致:
编辑:根据注释,需要对放置在JScrollPane中的对象执行set不透明(false)
例如:
list.setOpaque(false);
scrollpane.setViewportView(list);
正如MadProgrammer所建议的,JLayer确实可以工作:
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.*;
public class FixedImageLayerUI extends LayerUI<JComponent>
{
@Override
public void paint(Graphics g, JComponent c)
{
super.paint(g, c);
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor( Color.RED );
g2.fillOval(0, 0, 10, 10);
g2.dispose();
}
private static void createAndShowUI()
{
String[] data =
{
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
"k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
"u", "v", "w", "x", "y", "z"
};
JList<String> list = new JList<String>( data );
JScrollPane scrollPane = new JScrollPane( list );
LayerUI<JComponent> layerUI = new FixedImageLayerUI();
JLayer<JComponent> layer = new JLayer<JComponent>(scrollPane, layerUI);
JFrame frame = new JFrame("FixedImage");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( layer );
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.*;
public class FixedImageScrollPane
{
private static void createAndShowUI()
{
String[] data =
{
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
"k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
"u", "v", "w", "x", "y", "z"
};
JList<String> list = new JList<String>( data );
list.setOpaque( false );
JScrollPane scrollPane = new JScrollPane( list )
{
@Override
public void paint(Graphics g)
{
super.paint(g);
g.setColor( Color.RED );
g.fillOval(0, 0, 10, 10);
}
};
JFrame frame = new JFrame("FixedImage");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( scrollPane );
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
import java.awt.*;
导入javax.swing.*;
导入javax.swing.plaf.*;
公共类FixedImageLayerUI扩展了LayerUI
{
@凌驾
公共空隙涂料(图形g、J组件c)
{
超级油漆(g,c);
Graphics2D g2=(Graphics2D)g.create();
g2.设置颜色(颜色为红色);
g2.椭圆形(0,0,10,10);
g2.dispose();
}
私有静态void createAndShowUI()
{
字符串[]数据=
{
“a”、“b”、“c”、“d”、“e”、“f”、“g”、“h”、“i”、“j”,
“k”、“l”、“m”、“n”、“o”、“p”、“q”、“r”、“s”、“t”,
“u”、“v”、“w”、“x”、“y”、“z”
};
JList列表=新的JList(数据);
JScrollPane scrollPane=新的JScrollPane(列表);
LayerUI LayerUI=新的FixedImageLayerUI();
JLayer layer=新的JLayer(滚动窗格,layerUI);
JFrame frame=新JFrame(“固定图像”);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
框架。添加(层);
frame.pack();
frame.setLocationByPlatform(真);
frame.setVisible(true);
}
公共静态void main(字符串[]args)
{
invokeLater(新的Runnable()
{
公开募捐
{
createAndShowUI();
}
});
}
}
此外,正如MadProgrammer所指出的那样
import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.*;
public class FixedImageScrollPane
{
private static void createAndShowUI()
{
String[] data =
{
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j",
"k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
"u", "v", "w", "x", "y", "z"
};
JList<String> list = new JList<String>( data );
list.setOpaque( false );
JScrollPane scrollPane = new JScrollPane( list )
{
@Override
public void paint(Graphics g)
{
super.paint(g);
g.setColor( Color.RED );
g.fillOval(0, 0, 10, 10);
}
};
JFrame frame = new JFrame("FixedImage");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( scrollPane );
frame.pack();
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}
public class GlassFrame {
private JPanel panel;
private JScrollPane scrollPane;
private BufferesImage img;
public GlassFrame() {
panel = new JPanel(){
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
img = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setPaint(Color.WHITE);
Rectangle2D rect = new Rectangle2D.Float(0, 0, 420, 420);
g2.fill(rect);
g2.setPaint(Color.BLACK);
for (int i = 0; i <= 10; i++) {
g2.draw(new Line2D.Float(10 + i * 40,10,10 + i * 40,410));
g2.draw(new Line2D.Float(10,10 + i * 40,410,10 + i * 40));
}
g2.dispose();
g.drawImage(img, 0, 0, this);
}
};
panel.setPreferredSize(new Dimension(420, 420));
panel.setOpaque(false);
scrollPane = new JScrollPane(panel, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.getVerticalScrollBar().setUnitIncrement(10);
JFrame frame = new JFrame("ScrollPane and GlassPane");
final GlassPane glass = new GlassPane(scrollPane.getViewport());
frame.setGlassPane(glass);
JTabbedPane tab = new JTabbedPane();
JPanel panelInTab = new JPanel();
panelInTab.setLayout(new BorderLayout());
tab.add("first tab", panelInTab);
tab.add("second tab", new JPanel());
panelInTab.add(scrollPane, BorderLayout.CENTER);
panelInTab.add(new JButton("testbutton"), BorderLayout.NORTH);
panelInTab.addComponentListener(new ComponentAdapter() {
@Override
public void componentShown(ComponentEvent arg0) {
glass.setVisible(true);
}
@Override
public void componentHidden(ComponentEvent arg0) {
glass.setVisible(false);
}
});
frame.getContentPane().add(tab);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setPreferredSize(new Dimension(300, 400));
frame.pack();
frame.setLocation(200, 200);
frame.setVisible(true);
glass.setVisible(true);
}
class GlassPane extends JPanel{
private JViewport viewport;
private BufferedImage image = null;
public GlassPane(JViewport viewport){
setOpaque(false);
this.viewport = viewport;
image = new BufferedImage(58, 58, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = image.createGraphics();
g2.setColor(Color.red);
g2.setStroke(new BasicStroke(3.0f));
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawOval(5, 5, 50, 50);
g2.dispose();
}
@Override
protected void paintComponent(Graphics g) {
Point vpLocation = viewport.getLocationOnScreen();
Point gpLocation = getLocationOnScreen();
int x = vpLocation.x - gpLocation.x;
int y = vpLocation.y - gpLocation.y;
super.paintComponent(g);
if (image != null) {
g.drawImage(image, x, y, this);
}
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
GlassFrame frame = new GlassFrame();
}
});
}
}