Java 如何在JFrame内部创建视口?

Java 如何在JFrame内部创建视口?,java,swing,jframe,Java,Swing,Jframe,目前我正在尝试制作一个类似于agar.io的游戏,我在滚动和视口方面遇到了问题。这是我的密码: import java.applet.Applet; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Toolkit; import javax.swing.JF

目前我正在尝试制作一个类似于agar.io的游戏,我在滚动和视口方面遇到了问题。这是我的密码:

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Toolkit;

import javax.swing.JFrame;

public class Game extends Applet{

    public void paint (Graphics g)
    {
        Player p = new Player("test");
        int centerX = p.getPos()[0];
        int centerY = p.getPos()[1];
        String name = p.getName();
        int fontSize = (int)Math.round(20 - name.length() / 1.5);
        for(int i = 0; i < p.getCells().length; i++){
            g.setFont(new Font("Monospaced", Font.BOLD, fontSize));
            g.setColor(p.getColor());
            g.fillOval(p.getPos()[0] - p.getCells()[i].getMass() / 2, p.getPos()[1] - p.getCells()[i].getMass() / 2, p.getCells()[i].getMass(), p.getCells()[i].getMass());
            g.setColor(new Color(0, 0, 0));
            g.drawString(p.getName(), (int)Math.round(centerX - name.length() * Math.round(fontSize / 3)), centerY + Math.round(fontSize / 3));
        }
    }

    public static void main(String args[])
    {
        Game a = new Game();
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        JFrame frame = new JFrame();    
        frame.setSize(100000, 100000); 
        frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(a, BorderLayout.CENTER);
        frame.setVisible(true);
    }
}
单元格对象代码:

public class Cell {
    private int xCoor, yCoor, mass;
    public Cell(){
        xCoor = (int)(Math.random() * 10000);
        yCoor = (int)(Math.random() * 10000);
        mass = 100;
    }
    public void setX(int x){
        xCoor = x;
    }
    public void setY(int y){
        yCoor = y;
    }
    public void setMass(int m){
        mass = m;
    }
    public int getX(){
        return xCoor;
    }
    public int getY(){
        return yCoor;
    }
    public int getMass(){
        return mass;
    }
}
这幅画很好地表达了我的愿望

基本上,通过绘画绘制的内容显示在整个JFrame中(我想我已经实现了,如果我错了请纠正我),但我只希望用户能够查看其中的一小部分


我相信要做到这一点,您需要使用JViewPort和JScrollPane,但我不知道如何在代码中实现这一点。如果有任何帮助,我们将不胜感激。

我的情况与您的类似,我实现了类似的功能。我不知道这是否理想,如果有人能证实,我将不胜感激。它确实完成了我正在寻找的工作,但是缓慢的帧速率没有帮助

import javax.swing.*;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

public class MovingAnimationJava7 extends Canvas {
    
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private BufferedImage canvas;
    private JViewport viewport;
    

    public MovingAnimationJava7(int width, int height) {
        canvas = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    }
    
    public void start() {
        Thread.currentThread();
        int i = 0;
        while(true) {
            try {
                repaint();
                Point point = new Point(i,i++);
                viewport.setViewPosition(point);
                Thread.sleep(100);
            }
            catch(Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void paint(Graphics g) {
        Random r = new Random();
        for (int x = 0; x < canvas.getWidth(); x++) {
            for (int y = 0; y < canvas.getHeight(); y++) {
                int red=r.nextInt(256);
                int green=r.nextInt(256);
                int blue=r.nextInt(256);
                Color c=new Color(red,green,blue);
                int color = c.getRGB();
                canvas.setRGB(x, y, color);
            }
        }
        
        Graphics2D g2 = (Graphics2D) g;
        g2.drawImage(canvas, null, null);
    }
    
    private JViewport getVP() { return viewport; }
    private void setVP(JViewport vp) { viewport = vp; }

    public static void main(String[] args) {
        MovingAnimationJava7 animatedCanvas = new MovingAnimationJava7(400,400);
        
        JViewport viewport = new JViewport();
        viewport.setSize(159, 143);
        viewport.add(animatedCanvas);
        Point point = new Point(0,0);
        viewport.setViewPosition(point);
        animatedCanvas.setVP(viewport);
        
        JFrame jp = new JFrame();
        jp.getContentPane().add(animatedCanvas.getVP(), BorderLayout.CENTER);
        jp.setSize(new Dimension(500,500));
        jp.setVisible(true);
        animatedCanvas.start();
    }
}
import javax.swing.*;
导入java.awt.*;
导入java.awt.image.buffereImage;
导入java.util.Random;
公共类MovingAnimationJava7扩展画布{
/**
* 
*/
私有静态最终长serialVersionUID=1L;
私有缓冲图像画布;
私有视口;
公共移动animationjava7(整数宽度、整数高度){
画布=新的BuffereImage(宽度、高度、BuffereImage.TYPE_INT_ARGB);
}
公开作废开始(){
Thread.currentThread();
int i=0;
while(true){
试一试{
重新油漆();
点=新点(i,i++);
viewport.setViewPosition(点);
睡眠(100);
}
捕获(例外e){
e、 printStackTrace();
}
}
}
公共空间涂料(图g){
随机r=新随机();
对于(int x=0;x
我认为这行不通。您应该在面板中显示图形,然后使用视口在面板上滚动。无论如何,您可能希望放弃视口功能,只需以不同的方式实现滚动
公共类游戏扩展小程序{..Game a=new Game();..JFrame frame=new JFrame();..frame.getContentPane().add(a,BorderLayout.CENTER)
Nope.最好转储
Applet
&而不是像
JPanel
那样扩展
JComponent
。覆盖
paintComponent(Graphics)
方法而不是
paint(…)
&立即调用
super
方法。
g.drawString(p.getName(),(int)Math.round(centerX-name.length())..
um..no.因为
name
是一个
字符串
,所以这个数字将是字符串中的字符数,而不是像素宽。对于和@andrewhompson,谢谢你的提示!我一定会放弃小程序,改用JPanel。至于绘制字符串,我知道它返回的长度是e字符串,但我用它作为一种棘轮方式来将圆圈内的文本居中。它适合我的目的,但有更好的方法吗?谢谢!
import javax.swing.*;

import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Random;

public class MovingAnimationJava7 extends Canvas {
    
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private BufferedImage canvas;
    private JViewport viewport;
    

    public MovingAnimationJava7(int width, int height) {
        canvas = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
    }
    
    public void start() {
        Thread.currentThread();
        int i = 0;
        while(true) {
            try {
                repaint();
                Point point = new Point(i,i++);
                viewport.setViewPosition(point);
                Thread.sleep(100);
            }
            catch(Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void paint(Graphics g) {
        Random r = new Random();
        for (int x = 0; x < canvas.getWidth(); x++) {
            for (int y = 0; y < canvas.getHeight(); y++) {
                int red=r.nextInt(256);
                int green=r.nextInt(256);
                int blue=r.nextInt(256);
                Color c=new Color(red,green,blue);
                int color = c.getRGB();
                canvas.setRGB(x, y, color);
            }
        }
        
        Graphics2D g2 = (Graphics2D) g;
        g2.drawImage(canvas, null, null);
    }
    
    private JViewport getVP() { return viewport; }
    private void setVP(JViewport vp) { viewport = vp; }

    public static void main(String[] args) {
        MovingAnimationJava7 animatedCanvas = new MovingAnimationJava7(400,400);
        
        JViewport viewport = new JViewport();
        viewport.setSize(159, 143);
        viewport.add(animatedCanvas);
        Point point = new Point(0,0);
        viewport.setViewPosition(point);
        animatedCanvas.setVP(viewport);
        
        JFrame jp = new JFrame();
        jp.getContentPane().add(animatedCanvas.getVP(), BorderLayout.CENTER);
        jp.setSize(new Dimension(500,500));
        jp.setVisible(true);
        animatedCanvas.start();
    }
}