[Resolvido]Modificando o viewport de um JScrollPane

7 respostas
E

Fala galera, seguinte:

Eu to desenvolvendo esse programa aqui, e to enfrentado algumas dificuldades.

A principal é o seguinte: quando a imagem é muito grande ou o zoom tá muito grande, e usuário desloca-se para uma determinada área da figura, ele trabalha naquela área sem problema. Até aí tudo bem. Mas, quando ele troca a imagem, como quando ele cria uma nova ou abre outra já existente, e tenta volta pra primeira figura ele não volta pra parte da imagem que ele tava editando, mas sim pro canto superior esquerdo da imagem, entendem, eu tentei contornar isso com o código abaixo, mas não funciona, pois de alguma forma ele se perde entre uma modificação do conteúdo do view port e outra. Observem o código:

Abaixo, segue o código que tenta salvar o ponto que ele tava editando e recuperar o da outra imagem entre uma troca de imagem pela outra:
/**
		 * Modifica o foco para imagem na posição indicada
		 * 
		 * @param posicao
		 *            a posição da imagem da lista desta instância
		 */
		public void modificaImagemFocada(int posicao) {
			if (posicao != this.nbFocada) {
				this.nbFocada = posicao;
			}
			getImagemAtual().setPontoVisivel( jspBase.getViewport().getViewPosition());//Esse método recebe um objeto do tipo point
			Imagem imagem = null;
			if (this.nbFocada < 0
					|| this.nbFocada >= this.getLsImagens().size()) {
				if (this.getLsImagens().size() == 0) {
					imagem = this.novaImagem();
				} else {
					this.nbFocada = this.getLsImagens().size() - 1;
					imagem = this.getLsImagens().get(this.nbFocada);
				}
			} else {
				imagem = this.getLsImagens().get(this.nbFocada);
			}
			dmTamanho.setSize(imagem.getTamanho().getWidth()*imagem.getZoom(), imagem
					.getTamanho().getHeight()*imagem.getZoom());// é o tamanho da área de desenho sendo modificado
			jpArea.revalidate();//é a area de desenho sendo redimensionada
			dsDesenhista.defineImagem(imagem);
			jpArea.repaint();
			
			jspBase.revalidate();// é o scroll pane onde está a área de desenho sendo revalidado
			SwingUtilities.invokeLater(new Runnable() {
				
				@Override
				public void run() {
					// TODO Auto-generated method stub
					jspBase.getViewport().setViewPosition(getImagemAtual().getPontoVisivel());
					
				}
			});
			
			
			setStNomeImgAtual(imagem);

			aDesfazer.setEnabled(getImagemAtual().getDesfazerRefazer().canUndo());
			aRefazer.setEnabled(getImagemAtual().getDesfazerRefazer().canRedo());
			
			this.atualizaMenu();
		}

7 Respostas

E

up!

E

E então galera, ninguém?

E

Up!

Eric_Yuzo

O método para posicionar o scroll pane está certo. Tente debugar para ver se o getImagemAtual() está retornando o objeto esperado.

E

Sim está. O problema aparentemente é que mesmo quando eu mando aumentar o jpanel dentro do viewport, o mesmo não aumenta de imediato. Leva um tempo pro viewport aumentar, Já tentei usar o invokeLater() do Swing, mas não foi.

Tentei então usar o Property listenner, e por incrível que pareça, quando o tamanho muda, ele não é disparado. Por outro lado,se eu usar um propertychangelistenner, ele funciona, más não dá pra saber qual propriedade foi modificada(Ou dá?). Então, acho que minha única chance é herdar o JView port e reescreve-lo para atender minhas necessidades. Só que pra isso, eu preciso ver o código fonte dele. Alguém sabe onde eu posso ver o código fonte Swing?? Desde já, agradeço.

Eric_Yuzo

Estranho. O processamento pesado deveria “congelar” a tela, mas assim que terminado, o restante do método deveria executar normalmente. De qualquer forma, você deve disparar uma nova thread fora do swing para separar este processamento. E o invokeLater faz o contrário, que é fazer com que seu runnable execute dentro da thread do swing.

Sim, usando o método getPropertyName():

public void propertyChange(PropertyChangeEvent evt) { String propriedade = evt.getPropertyName(); . . . }

E

Bem, já tinha até deixado de lado, mas finalmente consegui achar o código da Jviewport. Olhando lá. descobri o que o Jcomponent já tem um listenner para redimensionamento. Então o código ficou assim:

JPanel mesa = new JPanel();
		mesa.setLayout(new BoxLayout(mesa, BoxLayout.X_AXIS));
		mesa.add(Box.createHorizontalGlue());
		mesa.add(this.jpArea);
		mesa.add(Box.createHorizontalGlue());
		mesa.setBackground(Color.gray);
		mesa.setPreferredSize(dmTamanho);
		mesa.addComponentListener(new ComponentListener() {
			
			@Override
			public void componentShown(ComponentEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void componentResized(ComponentEvent arg0) {
				// TODO Auto-generated method stub
				jspBase.getViewport().setViewPosition(giGerenciador.getImagemAtual().getPontoVisivel());
			}
			
			@Override
			public void componentMoved(ComponentEvent arg0) {
				// TODO Auto-generated method stub
				
			}
			
			@Override
			public void componentHidden(ComponentEvent arg0) {
				// TODO Auto-generated method stub
				
			}
		});
		
		this.jspBase.setViewportView(mesa);

Pra quem tiver problemas parecidos, eis a solução.

Criado 22 de maio de 2011
Ultima resposta 20 de set. de 2011
Respostas 7
Participantes 2