byte color have to keep colors (like red or green).
Result of show() method have to use switch to classify and describe this colors (in different variants like: red-blue, green-red etc.) *can't use enum
public class Candy {
//fields
int quantity;
byte color;
double price;
//constructor
Candy(int quantity, byte color, double price)
{
this.quantity = quantity;
this.color = color;
this.price = price;
}
//this method have to show class fields
public void show(String colors)
{
switch(color)
{
case 1: colors = "red";
case 2: colors = "green";
case 3: colors = "blue";
}
//tried to convert
//String red = "Red";
//byte[] red1 = red.getBytes();
//String green = "Green";
//byte[] green1 = green.getBytes();
public static void main(String[] args)
{
//program
}
}
Am I on good way? How to keep Strings in byte? Thanks
A switch is not a good choice, because you need a break in every case, which makes for a lot a code to do very little:
switch (color) {
case 1: colors = "red"; break;
... etc
Also, having so many lines means there is more scope for bugs.
But worse, you are essentially using code to store data.
A better choice is to use a Map and look up the String:
private static Map<Byte, String> map = new HashMap<Byte, String>() {{
put(1, "red");
put(2, "green");
etc
}};
then in your method simply
return map.get(color);
In one byte you can store 8 possible combinations.
In my decision I stated that first position (in binary representation of byte) is "blue" color, second - "green" and third - "red". This means if we have 001 - it's blue color. If 101 - its red-blue color and so on.
This is your show() method:
public void show()
{
switch (color & 4){
case 4:
System.out.print("red ");
default:
switch (color & 2){
case 2:
System.out.print("green ");
default:
switch (color & 1){
case 1:
System.out.print("blue");
}
}
}
System.out.println();
}
Calling of method:
new Candy(1, (byte)7, 10d).show(); //prints "red green blue"
Related
I have a method that takes in a Briefcase, and the user's selected briefcase number which holds a value. For example .getValue1() returns a JLabel. What can I do to shorten this switch case so I am not repeating code?
public void removeValueDisplay(Briefcase briefcase, int caseNum) {
switch (Model.briefcases[caseNum - 1].getValue())
{
case 1:
view.getValue1().setEnabled(false);
break;
case 2:
view.getValue2().setEnabled(false);
break;
case 5:
view.getValue5().setEnabled(false);
break;
case 10:
view.getValue10().setEnabled(false);
break;
case 25:
view.getValue25().setEnabled(false);
break;
}
}
There are 26 cases in total, which I haven't included in this code
Create an array of JLabel in your Briefcase class to store your labels. Then an accessor for all at once:
public JLabel[] getValues();
Or to retrieve only the one you want:
public JLabel getValue(int number);
Thanks for your help everyone. This how I've shortened my code:
public void removeValueDisplay(int caseNum) {
for (int i = 0; i < Model.briefcases.length; ++i) {
if(Model.briefcases[caseNum - 1].getValue() == Model.values[i]) {
view.getValueLabels()[i].setEnabled(false);
}
}
I have been scouring the internet for answers to my problem. I have found some good advice and have changed my original code, but I am yet to discover the answer to my initial problem.
I am trying to take string data from a series of Jtextfields and writing them to an arraylist, and then in turn taking the written data from the arraylist and transfering it to the same text fields.
public class Form extends javax.swing.JFrame {
public ArrayList<Personal> personalList;
public ArrayList<Business> businessList;
public ArrayList<Personal> displayPersonalList;
public ArrayList<Business> displayBusinessList;
public Form() {
initArrayLists();
}
private void initArrayLists(){
personalList = new ArrayList<Personal>();
businessList = new ArrayList<Business>();
displayPersonalList = new ArrayList<Personal>();
displayBusinessList = new ArrayList<Business>();
}
this is my submit button that writes to the arraylists.
private void submitButtonActionPerformed(java.awt.event.ActionEvent evt)
{
if (contactTypeLabel.getText().equals("Personal Contact")){
Personal p = new Personal();
p.first = firstNameTF.getText();
p.last = lastNameTF.getText();
p.address = addressTF.getText();
p.s = stateTF.getText();
p.zip = zipTF.getText();
p.phone = phoneTF.getText();
p.email = emailTF.getText();
personalList.add(p);
Personal d = new Personal();
d.first = firstNameTF.getText();
displayPersonalList.add(p);
resetTextFields();
}else if (contactTypeLabel.getText().equals("Business Contact")){
Business b = new Business();
b.first = firstNameTF.getText();
b.last = lastNameTF.getText();
b.address = addressTF.getText();
b.s = stateTF.getText();
b.zip = zipTF.getText();
b.phone = phoneTF.getText();
b.email = emailTF.getText();
businessList.add(b);
Business d = new Business();
d.first = firstNameTF.getText();
displayBusinessList.add(d);
resetTextFields();
}
}
here is the code to change to display mode, with a combobox that should populate for accessing the arraylist to fill the textfields with selected data
private void displayPersonalButtonActionPerformed(java.awt.event.ActionEvent evt)
{
personalFieldViewer();
submitButton.setVisible(false);
displayComboBox.setVisible(true);
clearTextFields();
for (Object item : displayPersonalList) {
displayComboBox.addItem(item);
}
}
this is the code for the combobox action and code to fill the text fields
private void displayComboBoxActionPerformed(java.awt.event.ActionEvent evt)
{
int x;
switch (displayComboBox.getSelectedIndex()){
case 0:
for (x = 0; x < x + 8; x ++) {
switch (x){
case 0 :firstNameTF.setText(personalList.get(x).toString());
break;
case 1 :lastNameTF.setText(personalList.get(x).toString());
break;
case 2 :addressTF.setText(personalList.get(x).toString());
break;
case 3 :stateTF.setText(personalList.get(x).toString());
break;
case 4 :zipTF.setText(personalList.get(x).toString());
break;
case 5 :phoneTF.setText(personalList.get(x).toString());
break;
case 6 :dobTF.setText(personalList.get(x).toString());
break;
case 7 :emailTF.setText(personalList.get(x).toString());
break;
}
}
break;
case 1:
for (x = 8; x < x + 8; x ++) {
switch (x){
case 8 :firstNameTF.setText(personalList.get(x).toString());
break;
case 9 :lastNameTF.setText(personalList.get(x).toString());
break;
case 10 :addressTF.setText(personalList.get(x).toString());
break;
case 11 :stateTF.setText(personalList.get(x).toString());
break;
case 12 :zipTF.setText(personalList.get(x).toString());
break;
case 13 :phoneTF.setText(personalList.get(x).toString());
break;
case 14 :dobTF.setText(personalList.get(x).toString());
break;
case 15 :emailTF.setText(personalList.get(x).toString());
break;
}
}
break;
case 2:
for (x = 16; x < x + 8; x ++) {
switch (x){
case 16 :firstNameTF.setText(personalList.get(x).toString());
break;
case 17 :lastNameTF.setText(personalList.get(x).toString());
break;
case 18 :addressTF.setText(personalList.get(x).toString());
break;
case 19 :stateTF.setText(personalList.get(x).toString());
break;
case 20 :zipTF.setText(personalList.get(x).toString());
break;
case 21 :phoneTF.setText(personalList.get(x).toString());
break;
case 22 :dobTF.setText(personalList.get(x).toString());
break;
case 23 :emailTF.setText(personalList.get(x).toString());
break;
}
}
break;
}
}
here are the classes that hold the variables for the arraylists.
public class Contacts {
public String first, last, address, s, zip, phone, email;
}
public class Personal extends Contacts{
public String dob;
}
public class Business extends Contacts{
public String title, organization;
}
when I alternately try to fill the arraylists with *.add(textfield.getText()); Java will not allow this as well as using variables first=firstNameTF.getText(); then *.add(first); I get the same error message...
Please try to refrain from being negative, and I have read the API regarding arraylists. Thank you.
Your arraylist declarations has type either Personal or Business. So these list cant add a string value. So when you say personalList.add(textfield.getText()); its actually trying to add String object to a list that can contain only Personal object.
Secondly the for loop inside displayComboBoxActionPerformed() method results in an infinite loop. for (x = 0; x < x + 8; x ++). Insted of having different for loops and switch statements you could do something like
private void displayComboBoxActionPerformed(java.awt.event.ActionEvent evt) {
if(displayComboBox.getSelectedIndex() > -1){
int start = displayComboBox.getSelectedIndex() * 8;
for (int x = start; x < start + 8; x ++) {
firstNameTF.setText(personalList.get(x).toString());
}
}
}
I'm trying to write a custom function to loop through an array list and compare the four sides of a quadrilaterals. Each side only needs to be compared 1 to 1 but I can't seem to be able to to figure out the correct way to loop through them. I drew up a diagram I attached bellow but I can't seem to implement the correct looping to do what I want to do. I made a simplified version of my Bounds class just for testing which uses a getSide(1-4) method to get the sides 1:North,2:East,3:South,4:West. For now I simply want to print the sides for my testing. i.e. (1 -> 11, 1 -> 11, 2 -> 8, 2 -> 12... ect.)
Edit: I forgot to mention the smallest numbers are the order I'm trying to get my algorithm to go through. Also maybe the tree is not as clear as I hoped, the lines are basiclicly going down comparing each side to of the quad to it's opposite. So the first sequence would be: Rectangle 1: 1 -> 7, then 1 -> 11, then move on to the eastern side and compare that to the west and so on until it goes through all for sides.
/* Program I'm using to test my algorithm */
public static void test()
{
BoundTest a,b,c,d,e,f;
a = new BoundTest("Rectangle 1","A","B","C","D");
b = new BoundTest("Rectangle 2","E","F","G","H");
c = new BoundTest("Rectangle 3","I","J","K","L");
ArrayList<BoundTest> x = new ArrayList();
x.add(0,a);
x.add(1,b);
x.add(2,c);
System.out.println(x.size());
for(int i = 0; i <= (x.size() - 2); i++)
{
System.out.println(x.get(i).getName());
}
}
/* Bounding Class */
public class BoundTest
{
private String north,east,south,west,name;
public BoundTest(String name,String a,String b,String c,String d)
{
this.name = "Name:" + name;
this.north = "North:" + a;
this.east = "East: " + b;
this.south = "South:" + c;
this.west = "West: " + d;
}
/* Get side */
public String getSide(int a)
{
String returnName;
switch(a)
{
case 1:
returnName = this.north;
break;
case 2:
returnName = this.east;
break;
case 3:
returnName = this.south;
break;
case 4:
returnName = this.west;
break;
default:
returnName = this.north;
break;
}
return returnName;
}
}
In my Java application, I was able to get the Color of a JButton in terms of red, green and blue; I have stored these values in three ints.
How do I convert those RGB values into a String containing the equivalent hexadecimal representation? Such as #0033fA
You can use
String hex = String.format("#%02x%02x%02x", r, g, b);
Use capital X's if you want your resulting hex-digits to be capitalized (#FFFFFF vs. #ffffff).
A one liner but without String.format for all RGB colors:
Color your_color = new Color(128,128,128);
String hex = "#"+Integer.toHexString(your_color.getRGB()).substring(2);
You can add a .toUpperCase()if you want to switch to capital letters. Note, that this is valid (as asked in the question) for all RGB colors.
When you have ARGB colors you can use:
Color your_color = new Color(128,128,128,128);
String buf = Integer.toHexString(your_color.getRGB());
String hex = "#"+buf.substring(buf.length()-6);
A one liner is theoretically also possible but would require to call toHexString twice. I benchmarked the ARGB solution and compared it with String.format() and the toHexString solution has a much higher performance:
Random ra = new Random();
int r, g, b;
r=ra.nextInt(255);
g=ra.nextInt(255);
b=ra.nextInt(255);
Color color = new Color(r,g,b);
String hex = Integer.toHexString(color.getRGB() & 0xffffff);
if (hex.length() < 6) {
hex = "0" + hex;
}
hex = "#" + hex;
Convert a java.awt.Color to a 24-bit hexadecimal RGB representation even if alpha channel value is zero (e.g. 0000ff):
String.format("%06x", 0xFFFFFF & Color.BLUE.getRGB())
For uppercase (e.g. 0000FF) :
String.format("%06X", 0xFFFFFF & Color.BLUE.getRGB())
This is an adapted version of the answer given by Vivien Barousse with the update from Vulcan applied. In this example I use sliders to dynamically retreive the RGB values from three sliders and display that color in a rectangle. Then in method toHex() I use the values to create a color and display the respective Hex color code.
This example does not include the proper constraints for the GridBagLayout. Though the code will work, the display will look strange.
public class HexColor
{
public static void main (String[] args)
{
JSlider sRed = new JSlider(0,255,1);
JSlider sGreen = new JSlider(0,255,1);
JSlider sBlue = new JSlider(0,255,1);
JLabel hexCode = new JLabel();
JPanel myPanel = new JPanel();
GridBagLayout layout = new GridBagLayout();
JFrame frame = new JFrame();
//set frame to organize components using GridBagLayout
frame.setLayout(layout);
//create gray filled rectangle
myPanel.paintComponent();
myPanel.setBackground(Color.GRAY);
//In practice this code is replicated and applied to sGreen and sBlue.
//For the sake of brevity I only show sRed in this post.
sRed.addChangeListener(
new ChangeListener()
{
#Override
public void stateChanged(ChangeEvent e){
myPanel.setBackground(changeColor());
myPanel.repaint();
hexCode.setText(toHex());
}
}
);
//add each component to JFrame
frame.add(myPanel);
frame.add(sRed);
frame.add(sGreen);
frame.add(sBlue);
frame.add(hexCode);
} //end of main
//creates JPanel filled rectangle
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawRect(360, 300, 10, 10);
g.fillRect(360, 300, 10, 10);
}
//changes the display color in JPanel
private Color changeColor()
{
int r = sRed.getValue();
int b = sBlue.getValue();
int g = sGreen.getValue();
Color c;
return c = new Color(r,g,b);
}
//Displays hex representation of displayed color
private String toHex()
{
Integer r = sRed.getValue();
Integer g = sGreen.getValue();
Integer b = sBlue.getValue();
Color hC;
hC = new Color(r,g,b);
String hex = Integer.toHexString(hC.getRGB() & 0xffffff);
while(hex.length() < 6){
hex = "0" + hex;
}
hex = "Hex Code: #" + hex;
return hex;
}
}
A huge thank you to both Vivien and Vulcan. This solution works perfectly and was super simple to implement.
slightly modified versions for RGBA from How to convert a color integer to a hex String in Android?
and How to code and decode RGB to Hex
public static String ColorToHex (Color color) {
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
int alpha = color.getAlpha();
String redHex = To00Hex(red);
String greenHex = To00Hex(green);
String blueHex = To00Hex(blue);
String alphaHex = To00Hex(alpha);
// hexBinary value: RRGGBBAA
StringBuilder str = new StringBuilder("#");
str.append(redHex);
str.append(greenHex);
str.append(blueHex);
str.append(alphaHex);
return str.toString();
}
private static String To00Hex(int value) {
String hex = "00".concat(Integer.toHexString(value));
hex=hex.toUpperCase();
return hex.substring(hex.length()-2, hex.length());
}
another way, this one could be related to the benchmark above:
public static String rgbToHex (Color color) {
String hex = String.format("#%02x%02x%02x%02x", color.getRed(), color.getGreen(), color.getBlue(), color.getAlpha() );
hex=hex.toUpperCase();
return hex;
}
a very simple benchmark shows that solution with String.format is 2+ times slower than StringBuilder for 10 million color conversions. For small amount of objects you cannot really see a difference.
I am not an expert so my opinion is subjective. I'm posting the benchmark code for any use, replace methods rgbToHex, rgbToHex2 with those you want to test:
public static void benchmark /*ColorToHex*/ () {
Color color = new Color(12,12,12,12);
ArrayList<Color> colorlist = new ArrayList<Color>();
// a list filled with a color i times
for (int i = 0; i < 10000000; i++) {
colorlist.add((color));
}
ArrayList<String> hexlist = new ArrayList<String>();
System.out.println("START TIME... " + ZonedDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME) + " TEST CASE 1...");
for (int i = 0; i < colorlist.size(); i++) {
hexlist.add(rgbToHex(colorlist.get(i)));
}
System.out.println("END TIME... " + ZonedDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME) + " TEST CASE 1...");
System.out.println("hexlist.get(0)... "+hexlist.get(0));
ArrayList<String> hexlist2 = new ArrayList<String>();
System.out.println("START TIME... " + ZonedDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME) + " TEST CASE 2...");
for (int i = 0; i < colorlist.size(); i++) {
hexlist2.add(rgbToHex1(colorlist.get(i)));
}
System.out.println("END TIME... " + ZonedDateTime.now().format(DateTimeFormatter.ISO_LOCAL_TIME) + " TEST CASE 2...");
System.out.println("hexlist2.get(0)... "+hexlist2.get(0));
}
it seems that there are issues with Integer.toHexString(color.getRGB())
try it with Color color = new Color(0,0,0,0); and you will find out that we have subtraction of zeros. #0 instead of #00000000 and we need all digits in order to have valid hex color values, 6 or 8 if with Alpha. So as far as I can see we need an improved use of Integer.toHexString to handle those cases. There should be other cases that cannot handle leading zeros at hex values. For example try with #0c0c0c0c that corresponds to Color color = new Color(12,12,12,12); The result will be #C0C0C0C witch is wrong.
Here is a 2 line version that also encodes the alpha value. These other examples are too verbose.
int rgba = (color.getRGB() << 8) | color.getAlpha();
return String.format("#%08X", rgba);
As in, the value as the end where it says "X dollars converts to Y russian ruble" (after the two Digits new Decimal Format) - the problem is that it can be russian ruble, british pound, or euro. How can I differentiate? (text inserted at line in question)
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.text.DecimalFormat;
public class CurrencyConversion extends Applet implements ItemListener
{
//declare variables and color
double dollars, answer;
int empCode;
Image dollarSign;
Color darkRed = new Color(160, 50, 0);
//Create components for applet
Label promptLabel = new Label("Enter the dollar amount (do not use commas or dollar signs):");
TextField currencyField = new TextField(20);
Label codeLabel = new Label ("Select the desired currency:");
CheckboxGroup codeGroup = new CheckboxGroup () ;
Checkbox britishpoundBox = new Checkbox("British Pound",false,codeGroup);
Checkbox euroBox = new Checkbox("Euro",false,codeGroup);
Checkbox russianrubleBox = new Checkbox("Russian Ruble",false,codeGroup);
Checkbox hiddenBox = new Checkbox("",true,codeGroup);
Label outputLabel = new Label("Click an option to convert the desired currency.");
public void init()
{
setBackground(darkRed);
setForeground(Color.white);
add(promptLabel);
add(currencyField);
currencyField.requestFocus();
currencyField.setForeground(Color.black);
add(codeLabel);
add(britishpoundBox);
britishpoundBox.addItemListener(this);
add(euroBox);
euroBox.addItemListener(this);
add(russianrubleBox);
russianrubleBox.addItemListener(this);
add(outputLabel);
}
//This method is triggered by click
public void itemStateChanged(ItemEvent choice)
{
try
{
dollars = getCurrency();
empCode = getCode();
answer = getComm(dollars,empCode);
output(answer, dollars);
}
catch (NumberFormatException e)
{
outputLabel.setText("You must enter a dollar amount greater than zero.");
hiddenBox.setState(true);
currencyField.setText("");
currencyField.requestFocus();
}
}
public double getCurrency()
{
double currency = Double.parseDouble(currencyField.getText());
if (currency <= 0) throw new NumberFormatException();
return currency;
}
public int getCode()
{
int code = 0;
if (britishpoundBox.getState()) code = 1;
else
if (euroBox.getState()) code = 2;
else
if (russianrubleBox.getState()) code = 3;
return code;
}
public double getComm(double currency, int code)
{
double amount = 0.0;
switch(code)
{
case 1:
amount = .79610 * currency;
break;
case 2:
amount = .70880 * currency;
break;
case 3:
amount = 35.88240 * currency;
break;
}
return amount;
}
public void output(double amount, double currency)
{
DecimalFormat twoDigits = new DecimalFormat("##.00");
outputLabel.setText("Your amount of " + twoDigits.format(currency) + " dollars converts to " + twoDigits.format(amount) RIGHT HERE - what do I do? );
}
public void paint(Graphics g)
{
dollarSign = getImage(getDocumentBase(), "dollarsign.gif");
g.drawImage(dollarSign,12,28,this);
}
}
Create a mapping from Integer to String, populate it with the various currency descriptions, and pass the Integer to the output function so that you can get the description from the mapping.
Wrap the currency concept into its own object. Override the ToString() method and return the name of the currency or define an explicit property to return the currency type. Pass the currency object around instead of the not so complex double and make the rate which was previously the double a property on the object.
I'd suggest you to use class java.util.Currency. The exchange rate of each currency should not be hard coded. For first phase just put it into properties file, i.e.:
RUB=35.88240
GBP=.79610
Avoid using hard coded list of currencies. Instead parse this property file, extract all keys, then use Currency.getInstance(currencyCode). Both UI and logic will be generic. Your application will be at least twice shorter and much more flexible.