So I have a class LayerCopper that holds a few textboxes and a few methods to set values in those textboxes:
public class LayerCopper extends javax.swing.JPanel {
public LayerCopper() {
initComponents();
}
private static javax.swing.JFormattedTextField CuWeightTextField;
private static javax.swing.JFormattedTextField LayerNumJFormattedTextField;
...
...
...
public void setLayerNumberText(int layerNumber) {
LayerNumJFormattedTextField.setText("" + layerNumber);
}
public void setLayerCuThickness(double CuThickness) {
CuWeightTextField.setValue(CuThickness);
}
}
I also have another class StackupCalculator with multiple instances of the LayerCopper panels in it. I have an arraylist that holds each instance of the LayerCopper panel:
static ArrayList<LayerCopper> layerSet_Copper = new ArrayList<>();
...
...
...
public void createLayerSetArray() {
layerSet_Copper.add(layerCopper1);
layerSet_Copper.add(layerCopper2);
layerSet_Copper.add(layerCopper3);
layerSet_Copper.add(layerCopper4);
layerSet_Copper.add(layerCopper5);
initializeLayerArrayValues();
}
When my initializeLayerArrayValues runs, It's supposed to populate a couple textfields with text:
private void initializeLayerArrayValues() {
for (int i = 0; i < layerSet_Copper.size(); i++) {
layerSet_Copper.get(i).setLayerNumberText(i + 1);
layerSet_Copper.get(i).setLayerCuThickness(0.750);
}
}
When I run the program though it doesn't update the fields. I'm guessing I am calling the main class LayerCopper and not the instanced version of it? How would I call the instanced version of the layer?
According to you, you haven't instantiated LayerCopper. You need to make a new instance of it, and make layerCopper1, layerCopper2, etc. Then use createLayerSetArray().
Like so:
LayerCopper lc = new LayerCopper();
// create values different layerCoppers to go in layerSet_Copper
lc.createLayerSetArray();
I don't quite understand the inner workings of your class, so I could be wrong.
Changing the textfields from static to non-static fixed it for me. /cheers
Related
I want to create a list, add blocks to it and then use it in a BlockBreakEvent to check if the block is in the list and cancel the event if it's not. But I can't seem to create and add things in it any other way than in the actual event itself (which looks to me like it would create issues). The only thing that is working for me is creating the list in the event and adding blocks to it one by one which looks really messy compared to: creating the list in a separate class and just checking the list with if(Listname.contains(block)) does anyone know how I can achieve this? Whether its dependency injection, or whatever else. I just can't figure out how to put it to use.
Here's what I've tried and is currently working for me, but I believe it's theoretically incorrect:
public class Event implements Listener {
#EventHandler
public void onBreak(BlockBreakEvent e) {
List<Material> allowedblocks = new ArrayList<Material>();
allowedblocks.add(Material.STONE);
//repeat this 10-50 times for whatever item
Player p = e.getPlayer();
Material block = e.getBlock().getType();
if(allowedblocks.contains(block)){
p.sendMessage("Invalid block. Break cancelled");
e.setCancelled(true);
}else{
p.sendMessage("Valid Block");
}
}
}
You can make allowedBlocks List a class field and fill it with elements inside of the constructor.
public class YourClass {
private List<Material> allowedBlocks = new ArrayList<>();
public YourClass() {
allowedBlocks.add(Material.STONE);
//repeat this 10-50 times for whatever item
}
#EventHandler
public void onBreak(BlockBreakEvent e) {
Player p = e.getPlayer();
Material block = e.getBlock().getType();
if(allowedBlocks.contains(block)){
p.sendMessage("Valid Block");
} else {
p.sendMessage("Invalid block. Break cancelled");
e.setCancelled(true);
}
}
}
Another approach would be to make the list static and fill it with values inside of a static block. I would not recommend making the list static if you are planning to change its values, but if your allowed blocks are going to remain the same, it may be a good idea to even go further and make it public, so you can access it from anywhere without an instance of YourClass
public class YourClass {
public static final List<Material> allowedBlocks;
static {
List<Materials> list = new ArrayList<>();
list.add(Material.STONE);
//repeat this 10-50 times for whatever item
//use an unmodifiable list,
//so you do not accidentally change its content later
allowedBlocks = Collections.unmodifiableList(list);
}
#EventHandler
public void onBreak(BlockBreakEvent e) {
Player p = e.getPlayer();
Material block = e.getBlock().getType();
if(allowedBlocks.contains(block)){
p.sendMessage("Valid Block");
} else {
p.sendMessage("Invalid block. Break cancelled");
e.setCancelled(true);
}
}
}
In the first case, there will be a list of allowedBlocks per instance of YourClass, which means, that every time you call new YourClass() a new List will be created and filled. In the second case, there will be only one list which will be created and populated on class loading (at the very beginning of the program) start up.
P.S. I would rather use a Set instead of a List here, considering you are using contains very often.
Since you are using an enum to store your Material types, you can simply call the static .values() method through Material.
Ex:
#EventHandler
public void onBreak(BlockBreakEvent e) {
Player p = e.getPlayer();
Material block = e.getBlock().getType();
if(List.of(Material.values()).contains(block)){
p.sendMessage("Invalid block. Break cancelled");
e.setCancelled(true);
}else{
p.sendMessage("Valid Block");
}
}
}
If you need to be able to customize what values are in the List you can use the singleton pattern to access that information globally.
The instance can be accessed statically from anywhere in the application:
import java.util.List;
public class BlockController {
public static BlockController instance = new BlockController();
private List<Material> allowedBlocks;
public BlockController() {
this.allowedBlocks = new ArrayList<>();
}
public void addAllowedBlock(Material mat) {
this.allowedBlocks.add(mat);
}
public void removeAllowedBlock(Material mat) {
this.allowedBlocks.remove(mat);
}
public boolean containsBlock(Material mat) {
return this.allowedBlocks.contains(mat);
}
public void clear() {
this.allowedBlocks.clear();
}
/**
* You can add more functionality here...
* This class can be accessed anywhere in the application
*
* use:
*
* BlockController controller = BlockController.instance;
* controller.containsBlock(Material.BLOCK);
*/
}
One approach to creating the list in a separate class is to use a static initializer block:
public class MyClass {
public static final List<Material> ALLOWED_MATERIALS = new ArrayList<>();
static {
ALLOWED_MATERIALS.add( Material.STONE );
}
public static List<Material> getAllowedMaterials() {
return Collections.unmodifiableList( ALLOWED_MATERIALS );
}
...
}
Try to create the List in a static context. This way the list is the same for all instances:
public class MyClass {
public static List<Material> allowedblocks = new ArrayList<Material>();
#EventHandler
public void onBreak(BlockBreakEvent e) {
allowedblocks.add(Material.STONE);
...
Then you can call the List from everywhere like this (e.g. if statement):
if(MyClass.allowedblocks.contains(block))
Your problem seems similar to this question, maybe this answer helps too: .
OK. After spending literally a few hours trying to get things working I give up.
Basically I am creating a program in which user inputs some values, then after hitting button a new scene is created and depending on the values it was given, different things take place.
My problem - I created "Settings.class" with a few variables with getters and setters. My assumption was to store the values input in there and whenever needed I have easy access to them using getters.
For some reason it doesn't work.
Keep in mind I simplified it as much as I can because It'd look very messy and would be very long if I pasted my original code. I made sure that the core of the problem is the same.
Settings class:
public class Settings {
private boolean diamonds;
public boolean getDiamonds() {
return diamonds;
}
public void setDiamonds(boolean diamonds) {
this.diamonds = diamonds;
}
}
Controller class:
public class Controller implements Initializable {
private Settings settings = new Settings();
private ProblematicOne prob = new ProblematicOne();
public void handleGoAction() throws IOException {
settings.setDiamonds(true);
prob.editText("This shall be set");
/* ..creating new stage and scene here no reason to paste it here, no probs with that.. */
#Override
public void initialize(URL location, ResourceBundle resources) {
}
}
}
And crème de la crème, problematic class:
public class ProblematicOne{
private Setting settings = new Settings();
String toBeEdited = ""; //
public void editText(String text){
if(settings.getDiamonds){ // for some reason it doesn't work; The getter returns false.
toBeEdited = text;
}else if(!settings.getDiamonds){
toBeEdited = "getDiamonds is false";
}
}
}
Alright, first off, what you are trying to do can be achieved by serializing the object (i.e Settings) and storing it. Or, simpler, just write to a file with values and load from there when you want to instantiate the class.
Look at this line in your "ProblematicOne"
private Setting settings = new Settings();
You just created a new instance of Settings. This instance does not have any idea of your Settings instance in your Controller.
Another way is to make your Settings class a singleton and then just reuse it. Example:
Settings.java
public class Settings {
private static Settings instance = null;
private boolean diamonds;
public boolean getDiamonds() {
return diamonds;
}
public void setDiamonds(boolean diamonds) {
this.diamonds = diamonds;
}
private Settings() {}
public static Settings getInstance(){
return instance == null ? new Settings() : instance;
}
}
Then in your Controller class just get the instance using the getInstance() method;
private Settings settings = Settings.getInstance();
Similarly, when you use it again in your ProblematicOne class, use the getInstance() method
Your issue is that ProblematicClass creates a new instance of settings, so the value is not accessible. You need to pass the same instance into the other class, or make your variables in settings class static, so you can access them without instance:
public class Settings {
private static boolean diamonds;
public static boolean getDiamonds() {
return diamonds;
}
public static void setDiamonds(boolean diamonds) {
this.diamonds = diamonds;
}
}
And use it without instance:
Settings.setDiamonds(true);
Settings.getDiamonds();
in the following class with out setting value to settings object, you are trying to use get, which will return default value.
public class ProblematicOne{
private Setting settings = new Settings();
String toBeEdited = ""; //
public void editText(String text){
if(settings.getDiamonds){ // for some reason it doesn't work; The getter returns false.
toBeEdited = text;
}else if(!settings.getDiamonds){
toBeEdited = "getDiamonds is false";
}
}
}
if you want to use the settings object which you created in the controller then pass settings object to editText method in the ProblematicOne class.
The problem is you are instantiating Setting class twice. You set the
settings.setDiamonds(true); //in one instance
and you expect to retrive this value in second instance in class ProblematicOne.
Try to solve this by instantiating Settings only once in Controller class and pass the same to ProblematicOne. Frame your code such that you instantiate
private Setting settings = new Settings();
only once in your whole application. Consider making this class singleton. Read about singleton instantiation here
http://www.javaworld.com/article/2073352/core-java/simply-singleton.html
How can I access my array from a different class? I have 3 classes; Main (where I want to access the array from) FramePanel (my GUI and where the value from UserInputNum is taken from) and StoryArray (where my array is saved).
I need to access the array in the nested If loop in the Main class, this is because I want too save the specific array data to a string and eventually append it into a JTextArea.
Here are the two classes needed:
Main.java
public class Main
{
public static String UserInput;
public static int UserInputNum;
public static void main(String[] args)
{
FramePanel.main();
StoryArray.main();
UserInputNum = Integer.parseInt(UserInput);
if (UserInputNum >= 0)
{
if (UserInputNum <= 399)
{
StoryArray.storyLine[UserInputNum];
}
else
{
}
}
else
{
}
}
}
StoryArray.java
public class StoryArray
{
public static String storyLine[] = null ;
public String[] getStoryLine()
{
return storyLine;
}
public static void main()
{
//String[] storyLine;
storyLine = new String[399];
storyLine[0] ("1")
storyLine[1] ("2")
storyLine[2] ("3")
storyLine[3] ("4")
storyLine[4] ("5")
storyLine[5] ("6")
In another class you can call the array like this:
String value = StoryArray.storyLine[index];
As it is a static public field you can access it directly by StoryArray.storyLine. But as you have a getter ethod I would suggest to make this getter setter static and the array field private and access it through getter method like that: StoryArray.getStoryLine() (to see why read about encapsulation).
You also shouldn't start your class (main) name from lower case, here are standard coding conventions for java language: http://www.oracle.com/technetwork/java/codeconvtoc-136057.html
Once you've called StoryArray.main(), then you should be able to do StoryArray.storyLine[/*element id*/] = "whatever you want" to get or set any element in storyLine. Additionally, you aren't defining any default array values. In StoryArray.main(), you need to have lines of the form storyLine[n] = "n".
Whatever I try to modify there's always a problem and the program won't run.
The thing is that my program works fine, when it's launched in the console, everything is ok, but when I try to make a GUI, and get text from console in the window, variables doesn't seem to work as they were.
The program is very simple, it has three packages like this:
//class SklepZoologiczny in package sklepzoologiczny
package sklepzoologiczny;
import javax.swing.JFrame;
import zwierzeta.*;
import magazyn.*;
public class SklepZoologiczny {
public static void main(String[] args) {
GUI GUI = new GUI();
GUI.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GUI.pack();
GUI.setSize(300, 500);
GUI.setVisible(true);
GUI.setTitle("Appka Zaliczeniowa - Sklep Zoologiczny");
GUI.setResizable(false);
GUI.setLocationRelativeTo(null);
}
}
//class GUI in package sklepzoologiczny
package sklepzoologiczny;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import magazyn.*;
import zwierzeta.*;
public class GUI extends JFrame {
public JLabel l_imie, l_gatunek, l_rasa;
public JButton b_dodaj, b_usun, b_lista;
public JTextField tf_imie, tf_gatunek, tf_rasa;
public String imie, gatunek, rasa;
public ArrayList lista_psow, lista_kotow;
public String pies, kot, gatunek_zwierza;
public String imie_psa, rasa_psa;
public String imie_kota, rasa_kota;
public GUI() {
setLayout(new FlowLayout());
b_dodaj = new JButton("Uruchom Program");
add(b_dodaj);
l_imie = new JLabel("Text from console to GUI should go here");
add(l_imie);
event dodanie = new event();
b_dodaj.addActionListener(dodanie);
}
public class event implements ActionListener {
public void actionPerformed(ActionEvent dodanie) {
magazyn magazyn1 = new magazyn();
magazyn1.kasa = 0;
pies pies1 = new pies();
kot kot1 = new kot();
krolik krolik1 = new krolik();
pies1.ustawImie("Max");
kot1.ustawImie("Nuta");
krolik1.ustawImie("Filip");
pies1.ustawCene(200);
kot1.ustawCene(100);
krolik1.ustawCene(50);
pies1.ustawRase("Jamnik");
kot1.ustawRase("Perski");
krolik1.ustawRase("Mini_Lop");
pies1.ustawGatunek("pies");
kot1.ustawGatunek("kot");
krolik1.ustawGatunek("krolik");
System.out.println("Operacje Zakupu Zwierzat");
System.out.println("---");
magazyn1.dodajZwierza(pies1);
magazyn1.dodajZwierza(kot1);
magazyn1.dodajZwierza(krolik1);
magazyn1.StanSklepu();
System.out.println("Transkacje");
System.out.println("---");
magazyn1.sprzedajZwierza("Nuta");
magazyn1.StanSklepu();
}
}
}
//class magazyn in package magazyn
package magazyn;
import java.util.ArrayList;
import zwierzeta.*;
public class magazyn {
public float kasa;
ArrayList <zwierzeta> lista = new ArrayList(20);
public void dodajZwierza(zwierzeta i){
lista.add(i);
sklepzoologiczny.GUI.l_rasa.setText("Do sklepu dodano zwierza o imieniu: " + i.wezImie());
}
public void sprzedajZwierza(String i){
for(int j=0; j<lista.size(); j++){
if(lista.get(j).wezImie() == i){
kasa = kasa + lista.get(j).wezCene();
lista.remove(j);
System.out.println("Sprzedano: " + i);
}
}
}
public void StanSklepu(){
System.out.println("Aktualny stan sklepu:");
for(int i=0; i<lista.size(); i++){
System.out.println(lista.get(i).wezImie()+", " +lista.get(i).wezGatunek()+", " + lista.get(i).wezRase() + ", cena: " + lista.get(i).wezCene());
}
System.out.println("Stan kasy \t\t\t" + kasa);
}
}
//class zwierzeta in package zwierzeta
package zwierzeta;
public abstract class zwierzeta {
String imie, gatunek, rasa;
float cena;
/* public void checkProduct() throws ProductException{
if(isDamaged == true){
ProductException damaged = new ProductException();
damaged.setErrorMessage("Product is damaged:");
throw damaged;
}
}*/
public void ustawImie(String i){
imie = i;
}
public String wezImie(){
return imie;
}
public void ustawGatunek(String i){
gatunek = i;
}
public String wezGatunek(){
return gatunek;
}
public void ustawRase(String i){
rasa = i;
}
public String wezRase(){
return rasa;
}
public void ustawCene(float i){
cena = i;
}
public float wezCene(){
return cena;
}
}
There are also three classes in package zwierzeta which only extends zwierzeta with no code in it.
So the thing is, whatever I try to put in the dodajZwierza in magazyn.java, there's always an error which says that I can't use non-static variable l_rasa to reference in a static context. I don't know how to fix this, I tried to make class as static in GUI but it just gets worse with more errors.
How can I get the text to appear in the window instead of a console?
First of all - you better avoid using members with names identical to type names:
GUI GUI = new GUI();
You - and the JVM - are more than likely to get confused by this, not knowing whether you are trying to access the class type or the class instance when you later run something like:
GUI.setVisible(true);
Second, if you want to let one class access a member of another class, it is much better to provide a getter that returns (a reference to ) that member, instead of defining the member as static and let the other classes access it directly.
You seem to conflate classes and instances: you want to create an instance of class GUI and then pass this instance around to be able to use the instance rather than the class.
In your main method, you create an instance of class GUI:
GUI GUI = new GUI();
The variable which refers to this instance you call GUI, the same as the class. This is a very bad idea. Java naming conventions dictate that variable names start with a non-capital letter, so you should write:
GUI gui = new GUI();
and change the rest of the main method accordingly.
Now, this instance gui is what you want to use. You have to pass it to the methods where you use it, and then write for example
gui.l_rasa.setText(...);
By the way, your code becomes more maintainable if you make the member variables of a class private, and add getter and setter methods to access them.
You are trying to access non static variable defined in GUI class as:
public JLabel l_imie, l_gatunek, l_rasa;
Here:
sklepzoologiczny.GUI.l_rasa.setText
I dont see its being initialised, but you could define it as static in GUI class like:
public static JLabel l_rasa;//initialize it may be and that would resolve your issue.
Hi I'm making an app but, I found a problem. I'm using netbeans gui builder to build my gui.
So, the first gui class has a lot of button(every button does the same function) that have an actionlistener that looks like this:
public class Guipanel extends JPanel {
private void jbtTTActionPerformed(java.awt.event.ActionEvent evt) {
if(mb.getlevel() > 16){
if(ttp != 20 && mb.getpoints() != 0){
point();
ttp++;
jbtTT.setText(""+ttp);
}
}
}
private void point(){
mb.reducepoints();
}
int ttp;
Base mb = new Base();
JButton jbtTT = new JButton();
}
The Base Class has a lot of method but the one that is related to this problem looks like this:
public class Base extends JFrame {
//point decrement method
public void reducepoints(){
points--;
jlbPoints.setText("Points Available: "+points);
}
//return point value
public int getpoints(){
return this.points;
}
//return level value
public int getlevel(){
return this.level;
}
private static int level = 1;
private static int points = 20;
private JLabel jlbPoints = new JLabel("Points Available: "+points);
}
So the problem is this, when I pressed the jbtTT the points variable will decrement so the value will change from 20 to 19. I used System.out.println to verify that. As you can see, the reducepoints() method should update the jlbPoints text which it doesnt. I have tried making the Base mb = new Base() to static Base mb = new Base() but it still doesn't work. Am I doing this wrong? Anyone have a suggestion?
EDIT: I've tried to do System.out.println(jlbPoints.getText()); and the text did changed. The only one that didn't change is the text that the user can see. Even repaint() and revalidate didn't work.
EDIT2: I finally found the answer to this question. I have to pass the 'Base' class object to the 'Guipanel' class since I created the 'Base' class object in a main class(I don't want to use this class as a main class). I passed it with the following method:
public void passObj(Base mb){
this.mb = mb;
}
and changing the constructor of 'Guipanel' class like this:
public Guipanel(Base mb) {
initComponents();
this.mb = mb;
}
also changing this Base mb = new Base(); to Base mb;
I wanted to thank everyone that have tried to answer this question.
Try using SwingUtilities.invokeLater() to ensure you are changing the text on the event dispatch thread, as you are supposed to. All we can do is guess given the current information.