【发布时间】:2017-05-29 18:04:30
【问题描述】:
大家好吗?如何在 Java 中直接在屏幕上呈现?我记得使用 setPixel 或 setRGB 进行此操作,但有一种方法可以设置主 JFrame 的像素并在 MS-Windows 组件之前设置 ZOrder。
这是代码和一个 *.ZIP 文件:
Mapa.java:
package com.primedi.ig;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.HeadlessException;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import com.primedi.matlog.C32;
import com.primedi.tech.Arquivo;
public class Mapa extends JFrame {
private static final long serialVersionUID = 1L;
public String nomeMapa = null;
private JPanel panMapa;
private JScrollPane brPanMapa;
public static Arquivo arqMapa = null;
Render r = null;
public Mapa(String nomeMapa){
this.nomeMapa = nomeMapa;
inicializarJanela();
try {
r = new Render();
r.setBounds(658, 10, 640, 480);
} catch (HeadlessException e) {
e.printStackTrace();
}
getContentPane().add(r);
setVisible(true);
processosCons();
}
private void criarJanela(){
//setTitle("zMeck - Início");
setSize(1352, 594);
getContentPane().setLayout(null);
setResizable(false);
setLocationRelativeTo(null);
setUndecorated(true);
getContentPane().setBackground(Color.BLACK);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private void criarPaineis(){
panMapa = new JPanel();
panMapa.setLayout(null);
panMapa.setBackground(Color.BLACK);
}
private void criarBarrasDeRolagem(){
brPanMapa = new JScrollPane(panMapa);
brPanMapa.setBounds(0, 0, 658, 498);
brPanMapa.getHorizontalScrollBar().setUnitIncrement(32);
brPanMapa.getVerticalScrollBar().setUnitIncrement(32);
arqMapa = new Arquivo("mapas", "teste.pmp");
arqMapa.carregarArquivo();
Dimension d = new Dimension((arqMapa.linhas.get(0).length() * 32), arqMapa.linhas.size() * 32);
panMapa.setPreferredSize(d);
}
private void adicionarComponentes(){
getContentPane().add(brPanMapa);
}
private void inicializarJanela(){
criarJanela();
criarPaineis();
criarBarrasDeRolagem();
adicionarComponentes();
//carregarInfosMapa();
}
/*private void carregarInfosMapa(){
arqMapa = new Arquivo("mapas", nomeMapa + ".pmp");
arqMapa.carregarArquivo();
Dimension d = new Dimension((arqMapa.linhas.get(0).length() * 32), arqMapa.linhas.size() * 32);
panMapa.setPreferredSize(d);
panMapa.setVisible(true);
for(int j = 0; j < alcanceY; j++){
for(int i = 0; i < alcanceX; i++){
tilesImaginarios[i][j] = new JLabel(new ImageIcon("tiles/tile0.PNG"));
tilesImaginarios[i][j].setBounds((i * 32) + 658, j * 32, 32, 32);
getContentPane().add(tilesImaginarios[i][j]);
}
}
}*/
public static int start = 0;
private void processosCons(){
Timer t = new Timer();
t.schedule(new TimerTask() {
int posInicialScrollX = 0;
int posInicialScrollY = 0;
public void run() {
if(start == 0){
start = 1;
}
if(brPanMapa.getViewport().getViewPosition().x != posInicialScrollX){
posInicialScrollX = brPanMapa.getViewport().getViewPosition().x;
Render.OFFSET_X = C32.pixelPara32(posInicialScrollX);
r.repaint();
return;
}
if(brPanMapa.getViewport().getViewPosition().y != posInicialScrollY){
posInicialScrollY = brPanMapa.getViewport().getViewPosition().y;
System.out.println("hello");
Render.OFFSET_Y = C32.pixelPara32(posInicialScrollY);
r.repaint();
return;
}
}
}, 33, 33);
}
}
渲染.java:
package com.primedi.ig;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.HeadlessException;
import java.awt.Image;
import java.awt.Toolkit;
import javax.swing.JPanel;
import com.primedi.tech.Arquivo;
public class Render extends JPanel {
private static final long serialVersionUID = 1L;
public static int OFFSET_X = 0;
public static int OFFSET_Y = 0;
public Render() throws HeadlessException {
super();
}
@Override
protected void paintComponent(Graphics g) {
if(Mapa.start == 1){
Graphics2D g2d = (Graphics2D)g;
Arquivo arq = new Arquivo("mapas", "teste.pmp");
arq.carregarArquivo();
for(int j = 0; j < 15; j++){
for(int i = 0; i < 20; i++){
System.out.println(OFFSET_X);
Image img1 = Toolkit.getDefaultToolkit().getImage("tiles/tile" + "" + arq.linhas.get(j + OFFSET_Y).charAt(i + OFFSET_X) + ".PNG");
g2d.drawImage(img1, i * 32, j * 32, this);
}
}
}
}
}
C32.java:
package com.primedi.matlog;
public class C32 {
public static int pixelPara32(int pixelV){
int aprox = 0;
int finalx = 0;
for(aprox = 0; aprox < pixelV; aprox++);
for(int i = 0; i < aprox; i = i + 32){
finalx++;
}
return finalx;
}
}
Arquivo.java:
package com.primedi.tech;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
public class Arquivo {
public ArrayList<String> linhas = new ArrayList<String>();
public String pasta;
public String arquivo;
public Arquivo(String pasta, String arq){
this.pasta = pasta;
arquivo = arq;
}
public void carregarArquivo(){
File file = new File(pasta + "/" + arquivo);
BufferedReader br;
try {
br = new BufferedReader(new FileReader(file));
String linha;
while ((linha = br.readLine()) != null) {
linhas.add(linha);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
当我在JScrollBar中插入jpanel方形渲染时,这是渲染过程中的错误,在图像总加载之前出现了JScrollPane的黑色背景,荒谬。
可以帮帮我吗?非常感谢各位。
这里是 *.ZIP 如果您觉得下载更好:https://expirebox.com/download/2b20ec8e44084c19d8bf1676d135d024.html
没有办法保留这个屏幕空间来渲染吗?
错误:bug
【问题讨论】:
-
这看起来与渲染无关,而与线程有关。您的代码看起来完全忽略了 Swing 线程规则,因此在发生长进程时,不会发生渲染。您提出的“修复”——直接渲染是XY Problem——对问题的错误解决方案。
-
建议的解决方案:查找并使用 SwingWorker。
-
好的,对不起,我会优化这个帖子
-
增加“brPanMapa.getComponent(0).setVisible(false);”在“criarBarrasDeRolagem”,我的代码继续快速,渲染基于 32x32 瓦片的地图速度非常快! 5小时后,我不知道我是怎么猜到这段代码的!
标签: java rendering jscrollpane