Pobranie wartości z klasy changelistenera

0

Witam,
Mam problem, który być może okaże się banalny, ale nie jestem w stanie wpaść na rozwiązanie.
W klasie Interface w konstruktorze tworze slidery i dodaje do do nich changelistenery w nastepujący sposób:

 
sac= new SlidersActionClass(this);
		slider2.addChangeListener(sac); 
		slider3.addChangeListener(sac); 
		slider4.addChangeListener(sac); 

Następnie w klasie SlidersActionClass tworzę wydarzenia dla tych suwaków i w zależności od ich wartości obliczam zmienną

 
public class SlidersActionClass implements ChangeListener {	
	double ev= 10;
	double evGetted;
	double iso, czasnaswietlania, przyslona;
	int ogniskowa;
	int isovalue, czasnaswietlaniavalue, przyslonavalue;
	int a, b;
	BufferedImage image, img;
	JLabel label1;
	JLabel EV;

	Interface nc;

	SlidersActionClass(Interface variable) { 
		nc = variable;
    	}
	
	@Override
	public void stateChanged(ChangeEvent e) {
////////jakiś tam kod

evGetted= Math.log((Math.pow(przyslona,  2))/(1/czasnaswietlania))/Math.log(2)- Math.log(iso/100)/Math.log(2);

////////dalszy kod

}

Klasa Interface to klasa w której tworze slidery.
Teraz chcę pobrać wartość, którą obliczyłem evGetted. Próbowałem to zrobić poprzez stworzenie metody get i w konstruktorze klasy Interface przekazuję tę wartość nowej zmiennej:

		exp= sac.getEvGetted();

Niestety, zmienna pozostaje ciąle pusta. Gdzie jest błąd w moim rozumowaniu?

EDIT
Zapomniałem wspomnieć, że wartości czasnaswietlania, przyslona są podpięte do suwaków za pomocą metody getValue()

0

i w konstruktorze klasy Interface przekazuję tę wartość nowej zmiennej
Zdecydowanie za wcześnie to robisz, metoda stateChanged jeszcze się ani razu nie wykonała. Skoro klasa SlidersActionClass ma referencję do klasy Interface, to w kodzie metody stateChanged zmieniaj wartości odpowiednich pól w klasie Interface.

0

to nie to, jeśli wrzucę do jakiegos listenera w klasie Interface
exp= sac.getEvGetted();

i wyświetle na kosoli to rzeczywiście sie będzie wyświetlać. Zależy mi jednak na tym, żeby móc tę wartość wykorzystać poza Listenerem. to jest w ogóle możliwe?

0

Oczywiście, że jest możliwe. Ale Ty nie wiesz, kiedy listener zadziałał i zmienił wartość tego pola. to listener powinien zmieniać pola w klasie Interface, coś w rodzaju

    SlidersActionClass(Interface variable) { 
        nc = variable;
        }
 
    @Override
    public void stateChanged(ChangeEvent e) {
////////jakiś tam kod
 
evGetted= Math.log((Math.pow(przyslona,  2))/(1/czasnaswietlania))/Math.log(2)- Math.log(iso/100)/Math.log(2);
 
////////dalszy kod
    nc.someField.setText(""+evGetted); 
}
0

Wypowiadam się dość nieprecyzyjnie, przepraszam. Może przybliże problem za pomocą kodu:

 		percent= 20;
		coip= new CopyOfImagePanel(700, 525, percent);
		ImageIcon ii= new ImageIcon(coip.getImg());
    	label = new JLabel(ii);
		label.setBounds(40, 70,700, 525);
		add(label);

W drugiej klasie z frame tworzę zdjęcie. Chciałbym, aby wartość percent zależała od obliczonej wartości evGetted, np:

 percent= evGetted/180;
		coip= new CopyOfImagePanel(700, 525, percent);
		ImageIcon ii= new ImageIcon(coip.getImg());
    	label = new JLabel(ii);
		label.setBounds(40, 70,700, 525);
		add(label);

Gdzie klasa CopyOfImagePanel: 
```cpp
public class CopyOfImagePanel extends RGBImageFilter {

	BufferedImage img, image;
	
	/*c, d- chosen height and weight
	procent- percent of image darken/ brighter
	*/
	public BufferedImage drawImage(BufferedImage newimage) {
		try {
			newimage = ImageIO.read(new File("java.bmp"));
		} 
		catch (IOException e1) {
			e1.printStackTrace();
		}	
		return newimage;
	}
		
	public CopyOfImagePanel(int c, int d, double procent) {
		super();
		image= drawImage(image);
		img = new BufferedImage(c,d, BufferedImage.TYPE_INT_RGB);
		RescaleOp op = new RescaleOp((float) procent/100, 0, null);
		image = op.filter(image, null);
		img.getGraphics().drawImage(image, 0, 0, c, d, null);

	}
	
	/*public BufferedImage makeDarkerBrighter(float procent) {
		RescaleOp op = new RescaleOp((float) procent/100, 0, null);
		image = op.filter(image, null);
		return image;
	}*/

	public BufferedImage getImage() {
		return image;
	}

	public BufferedImage getImg() {
		return img;
	}

	public void setImage(BufferedImage image) {
		this.image = image;
	}

	@Override
	public int filterRGB(int x, int y, int rgb) {
		// TODO Auto-generated method stub
		return 0;
	}
}
 
1

W czym problem?

    public void stateChanged(ChangeEvent e) {
////////jakiś tam kod
 
evGetted= Math.log((Math.pow(przyslona,  2))/(1/czasnaswietlania))/Math.log(2)- Math.log(iso/100)/Math.log(2);
 
////////dalszy kod
    nc.percent = evGetted; 
}

Jeśli pole percent jest private, to utwórz settera.

0

Ok, rzeczywiście tak zrobiłem. Teraz ppojawił się nowy problem, mianowicie chcę, aby wartość ta była wywoływana w nowej klasie

 public class AfterClick extends JFrame {

	private static final long serialVersionUID = 1L;
	Interface frame;
	CopyOfImagePanel coip;
	JLabel label;
	JButton back;
	JPanel panel;
	JLabel labelEv;
	String a;
	double exp;
	ImageIcon ii;
	JButton seeeffect;
	SlidersActionClass sac;
	ImageIcon image;
	double percent;
	
	
	public AfterClick() throws HeadlessException, IOException {
		
		setLayout(null);
		getContentPane().setBackground(Color.darkGray);
		
		frame= new Interface();
				
		labelEv= new JLabel("Wartość ekspozycji:"+ exp);
		labelEv.setForeground(Color.red);
		labelEv.setBounds(800, 200, 200, 100);
		add(labelEv);
		
    	label = new JLabel(Percent(ii));
		label.setBounds(40, 70,700, 525);
		add(label);
		
		panel= new JPanel();
		panel.setBounds(0, 50, 1600, 563);
		panel.setBackground(new java.awt.Color (28, 28, 28));
		add(panel);
		
		back= new JButton("return");
		back.setBounds(790, 70, 100, 100);
		add(back);
		
		seeeffect= new JButton("Click to see effect");
		seeeffect.setBounds(20,20, 40, 100);
		add(seeeffect);

	}

	public ImageIcon Percent(ImageIcon image) {
//w tym miejscu wywołuje konstruktor z parametrem, którego wartością powinna być evGetted. 
		coip= new CopyOfImagePanel(700, 525, 10*percent); 
		image= new ImageIcon(coip.getImg());
		return image;
	}
	public JButton getBack() {
		return back;
	}


	

Jednakże, zmienna ta nie chce działać, wyświetla się zdjęcie z zainteplemowaną wartością percent, zmienna ta nie ulega żadnym zmianom. O co chodzi?

0

O co chodzi?

Mam takie samo pytanie do Ciebie. Nic nie rozumiem z opisu Twojego problemu.

0

Ok, rzeczywiście moja wypowiedź jest dosyć pogmatwana. Postaram się więc jasno opisać mój problem.
Generalnie, piszę program który jest symulatorem aparatu fotograficznego.
Aktualnie posiadam 4 klasy, klasę główną:

public class Interface extends JFrame implements ChangeListener, ActionListener {

	private static final long serialVersionUID = 1L;
	static Interface xxx;
	static AfterClick yyy;
	final JButton button1, button2, button3, button4;
	final JButton takeapicture;
	final JSlider slider1, slider2, slider3, slider4;
	JLabel label1;
	final JLabel label2;
	final JLabel label3;
	final JLabel label4;
	final JLabel OGNISKOWA;
	final JLabel PRZYSLONA;
	final JLabel CZASNASWIETLANIA;
	final JLabel ISO;
	final JPanel panel2, panel3;
	final JRadioButton Av, Tv, Manual;
	final ButtonGroup buttGroup;
	int ogniskowa;
	int a= 400;
	int b= 300;
	BufferedImage image, img;
	CopyOfImagePanel pcoip;
	JButton returnxxx;
	JLabel EV;	
	String ev;
	double exp;
	SlidersActionClass sac;
	AfterClick ac;
	double percent;
	
	public Interface() throws HeadlessException, IOException {

		setLayout(null);
		getContentPane().setBackground(Color.darkGray);
		
		buttGroup= new ButtonGroup();
		Av= new JRadioButton("Av", true);
		Tv= new JRadioButton("Tv", false);
		Manual= new JRadioButton("Manual", false);
		Av.setBounds(475, 400, 40, 20);
		Tv.setBounds(515, 400, 40, 20);
		Manual.setBounds(480, 425, 80, 20);
		Av.setBackground(new java.awt.Color (28, 28, 28));
		Tv.setBackground(new java.awt.Color (28, 28, 28));
		Manual.setBackground(new java.awt.Color (28, 28, 28));
		Av.setForeground(new java.awt.Color (255, 255, 210));
		Tv.setForeground(new java.awt.Color (255, 255, 210));
		Manual.setForeground(new java.awt.Color (255, 255, 210));
		buttGroup.add(Av);
		buttGroup.add(Tv);
		buttGroup.add(Manual);
		add(Av);
		add(Tv);
		Tv.setVisible(true);
		add(Manual);
		Manual.setVisible(true);
		
		EV= new JLabel();
		add(EV);
		
		panel2= new JPanel();
		panel2.setBackground(new java.awt.Color (28, 28, 28));
		panel2.setBounds(450, 390, 120, 60);
		add(panel2);
		
		takeapicture= new JButton("Take a picture!");
		takeapicture.setBounds(450, 470, 120, 80);
		takeapicture.addActionListener(this);
		add(takeapicture);
		button1= new JButton("20");
		button2= new JButton("8.0");
		button3= new JButton("1/16");
		button4= new JButton("100");
		button1.setBackground(Color.WHITE);
		button2.setBackground(Color.WHITE);
		button3.setBackground(Color.WHITE);
		button4.setBackground(Color.WHITE);
		button1.setBounds(315, 450, 120, 20);
		button2.setBounds(315, 520, 120, 20);
		button3.setBounds(585, 450, 120, 20);
		button4.setBounds(585, 520, 120, 20);
		add(button1);
		add(button2);
		add(button3);
		add(button4);
		label1= new JLabel("Ogniskowa");
		label2= new JLabel("Przysłona");
		label3= new JLabel("Czas naświetlania");
		label4= new JLabel("Wartość ISO");
		label1.setForeground(Color.white);
		label2.setForeground(Color.white);
		label3.setForeground(Color.white);
		label4.setForeground(Color.white);
		label1.setBounds(350, 430, 200, 10);
		label2.setBounds(355, 500, 200, 10);
		label3.setBounds(600, 430, 200, 10);
		label4.setBounds(615, 500, 200, 10);
		add(label1);
		add(label2);
		add(label3);
		add(label4);
		slider1= new JSlider(20, 80, 20);
		slider2= new JSlider(1, 220, 80);
		slider3= new JSlider(1, 11, 7);
		slider4= new JSlider(1, 6, 1);
		
		slider1.setBackground(Color.darkGray);
		slider2.setBackground(Color.darkGray);
		slider3.setBackground(Color.darkGray);
		slider4.setBackground(Color.darkGray);
		slider1.setBounds(300, 470, 150, 30);
		slider2.setBounds(300, 540, 150, 30);
		slider3.setBounds(570, 470, 150, 30);
		slider4.setBounds(570, 540, 150, 30);
		
		sac= new SlidersActionClass(this);
		slider2.addChangeListener(sac); 
		slider3.addChangeListener(sac); 
		slider4.addChangeListener(sac); 
		slider2.setEnabled(true);
		slider3.setEnabled(true);
		slider4.setEnabled(true);

		add(slider1);
		add(slider2);
		add(slider3);
		add(slider4);	
		
		exp= sac.getEvGetted();		
		
		
		pcoip= new CopyOfImagePanel(400, 300, 100);
    	slider1.addChangeListener(this);
    	label1 = new JLabel(new ImageIcon(pcoip.getImg()));
		label1.setBounds(310, 40, 400, 300);
		add(label1);
		
		OGNISKOWA= new JLabel("22");
		OGNISKOWA.setForeground(Color.red);
		OGNISKOWA.setBounds(430, 335, 10000, 30);
		add(OGNISKOWA);
		PRZYSLONA= new JLabel("1.8");
		PRZYSLONA.setForeground(Color.red);
		PRZYSLONA.setBounds(480, 335, 10000, 30);
		add(PRZYSLONA);
		CZASNASWIETLANIA= new JLabel("1/2");
		CZASNASWIETLANIA.setForeground(Color.red);
		CZASNASWIETLANIA.setBounds(530, 335, 10000, 30);
		add(CZASNASWIETLANIA);
		ISO= new JLabel("100");
		ISO.setForeground(Color.red);
		ISO.setBounds(580, 335, 10000, 30);
		add(ISO);
		EV= new JLabel("EV: 10.0");
		EV.setForeground(Color.pink);
		EV.setBounds(660, 335, 10000, 30);
		add(EV);
				
		panel3= new JPanel();
		panel3.setBackground(new java.awt.Color (28, 28, 28));
		panel3.setBounds(290, 20, 440, 350);
		add(panel3);

	}
	
	
	public static void main(String[] args) throws HeadlessException, IOException {
		xxx= new Interface();
		xxx.setBackground(new java.awt.Color (5, 10, 20));
		xxx.setSize(1000, 700);
		xxx.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		xxx.setVisible(true);
		xxx.setTitle("SYMULATOR APARATU FOTOGRAFICZNEGO");
		
		yyy= new AfterClick();	
		yyy.getBack().addActionListener(xxx);
		yyy.setBackground(new java.awt.Color (5, 10, 20));
		yyy.setSize(1000, 700);
		yyy.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		yyy.setVisible(false);
		yyy.setTitle("SYMULATOR APARATU FOTOGRAFICZNEGO");
	}
	
	@Override
	public void stateChanged(ChangeEvent e) {
			ogniskowa= slider1.getValue();
			button1.setText("" + ogniskowa);
			OGNISKOWA.setText("" + ogniskowa);
			a= (int) (ogniskowa*400/20);
			b= (int) (ogniskowa*300/20);
			pcoip.getImg().getGraphics().drawImage(pcoip.getImage(),0, 0, a, b, null);
			repaint();
	}
    
	public void actionPerformed(ActionEvent e) {
		try {
			ac= new AfterClick();
		} catch (HeadlessException | IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
    	if (e.getSource()== takeapicture) {
    		xxx.setVisible(false);
    		yyy.setVisible(true);	
    		System.out.println(percent);
    	}
    	else if (e.getSource()== yyy.getBack()) {
    		yyy.setVisible(false);
    		xxx.setVisible(true);
    	}
    }


	public double getExp() {
		return exp;
	}


	public SlidersActionClass getSac() {
		return sac;
	}
	
}
 

W klasie tej buduje główny Interface oraz przechodzę przez nią do klasy tworzącej tnterface po wciśnięciu jednego z JButtonów, o nazwie AfterClick. W klasie głównej tworzę także JSlidery, których Listener stworzyłem w klasie zewnętrznej.
W tej zewnętrznej klasie obliczam wartość evGetted na podstawie wartości ustawionych na suwakach. Teraz zależy mi, aby wartość evGetted została przekazana do nowej wartości percent. To już, Twoim sposobem, osiągnąłem. Teraz zależy mi, aby wartość percent została wykorzystana przy wywoływaniu konstruktora klasy CopyOfImagePanel:

 public class AfterClick extends JFrame {

	private static final long serialVersionUID = 1L;
	Interface frame;
	CopyOfImagePanel coip;
	JLabel label;
	JButton back;
	JPanel panel;
	JLabel labelEv;
	String a;
	double exp;
	ImageIcon ii;
	JButton seeeffect;
	SlidersActionClass sac;
	ImageIcon image;
	double percent;
	
	
	public AfterClick() throws HeadlessException, IOException {
		
		setLayout(null);
		getContentPane().setBackground(Color.darkGray);
		
		frame= new Interface();
				
		labelEv= new JLabel("Wartość ekspozycji:"+ exp);
		labelEv.setForeground(Color.red);
		labelEv.setBounds(800, 200, 200, 100);
		add(labelEv);
		
    	label = new JLabel(Percent(ii));
		label.setBounds(40, 70,700, 525);
		add(label);
		
		panel= new JPanel();
		panel.setBounds(0, 50, 1600, 563);
		panel.setBackground(new java.awt.Color (28, 28, 28));
		add(panel);
		
		back= new JButton("return");
		back.setBounds(790, 70, 100, 100);
		add(back);

	}

	public ImageIcon Percent(ImageIcon image) {
		coip= new CopyOfImagePanel(700, 525, 10*percent);
		image= new ImageIcon(coip.getImg());
		return image;
	}
	public JButton getBack() {
		return back;
	}


	

}

Klasa CopyOfImagePanel wygląda tak:

public class CopyOfImagePanel extends RGBImageFilter {

	BufferedImage img, image;
	
	public BufferedImage drawImage(BufferedImage newimage) {
		try {
			newimage = ImageIO.read(new File("java.bmp"));
		} 
		catch (IOException e1) {
			e1.printStackTrace();
		}	
		return newimage;
	}
		
	public CopyOfImagePanel(int c, int d, double procent) {
		super();
		image= drawImage(image);
		img = new BufferedImage(c,d, BufferedImage.TYPE_INT_RGB);
		RescaleOp op = new RescaleOp((float) procent/100, 0, null);
		image = op.filter(image, null);
		img.getGraphics().drawImage(image, 0, 0, c, d, null);

	}

	public BufferedImage getImage() {
		return image;
	}

	public BufferedImage getImg() {
		return img;
	}

	public void setImage(BufferedImage image) {
		this.image = image;
	}

	@Override
	public int filterRGB(int x, int y, int rgb) {
		// TODO Auto-generated method stub
		return 0;
	}




}
 

Jak widać, zmienna ta powinna mi rysować zdjęcie o różnej ciemności/ jasności w zależności od wyliczonej wartości evGetted. Niestety, zdjęcie nie rysuje się w ogóle.

0

Ja nie widzę kodu rysującego zdjęcie. Rysowanie powinno się odbywać na panelu (JPanel) w metodzie paintComponent(Graphics g). Można np. w tej modzie wywołać g.drawImage(image,...) a image przygotować w pamięci.

0

Oczywiście, że jest rysowanie: img.getGraphics().drawImage(image, 0, 0, c, d, null);
zresztą, gdy wywołam konstryktor coip= new CopyOfImagePanel(700, 525, 100); wszystko działa, gdy wywołam coip= new CopyOfImagePanel(700, 525, 10*percent); to obraz nie chce się rysować.
Proszę spojrzeć na klasę AfterClick, tam w metodzie wywołuje konstruktor, następnie tworzę JLabel

1 użytkowników online, w tym zalogowanych: 0, gości: 1