How do I use text fields to set an ellipse's dimensions? - java

The project I am working on requires a text field for the user to enter the width of an ellipse. When the user clicks somewhere on a panel, it draws an ellipse with the specified width. When I ran it, the width never changed.
This is in initialize():
tTextWidth = new JTextField();
tTextWidth.setBounds(42, 457, 86, 20);
frame.getContentPane().add(tTextWidth);
tTextWidth.setColumns(10);JButton tSetWidth = new JButton("Set Width");
tSetWidth.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
SetTextToWidth(tTextWidth.getText());
}
});
This is right after initialize():
public void SetTextToWidth(String tWidth)
{
if(tWidth == null)
{
tWidth = "50";
}
int tIntWidth = Integer.parseInt(tWidth);
if(tIntWidth == 0)
{
tIntWidth = 50;
}
RoundSprite tSpriteWidth = new RoundSprite();
tSpriteWidth.SetSpriteWidth(tIntWidth);
}
This is in the class RoundSprite:
private float mX;
private float mY;
int mWidth;
int mHeight;
Color mColor;
void DrawSprite(Graphics2D g2)
{
AffineTransform tOldTransform = g2.getTransform();
g2.setColor(mColor);
g2.translate(mX, mY);
g2.draw(new Ellipse2D.Double(0, 0, mWidth, mHeight));
g2.setTransform(tOldTransform);
g2.translate(mX - (mWidth / 2), mY - (mHeight / 2));
}
public void SetSpriteWidth(int tWidth)
{
mWidth = tWidth;
}

So two main things...
One...
ActionListener will only be triggered when the user presses the action key for the platform, in most cases the Enter key, just so you know ;)
Two...
In your SetTextToWidth is creating a new instance of RoundSprite which has no context to what is been displayed on the screen...
I you thinking, this would mean that ALL instances RoundSprite should be changed, which is not what you want.
As discussed in this simular question, you first need to define which sprite you are actually trying to change and then apply the change you want to that specific instance (and repaint the output)...
Side Notes
You might like to have a read through Code Conventions for the Java TM Programming Language, it will make it easier for people to read your code and for you to read others

Related

How to put Object into a panel?

So I have a list of Object, with a random height and weight. I also have a random number of those objects into a variable.
What I'm trying to do is to print all those object into the correct panel (I have 2 panel).
First of, my GUI and Object class (Blocks) are 2 separated class. Into the GUI, I'm doing this :
private JPanel initPanelBloc() {
panelBloc = new JPanel();
bloc = new Bloc(false);
panelBloc.add(bloc);
return panelBloc;
}
My Bloc class :
public class Bloc extends JPanel{
private int hauteur, largeur, nombreBloc;
private boolean premierPassage = true;
private ArrayList<Bloc> listeBlocRestant;
private Random rand = new Random();
public Bloc(boolean premierPassage) {
this.hauteur = 10 + rand.nextInt(50 - 10);
this.largeur = 10 + rand.nextInt(50 - 10);
listeBlocRestant = new ArrayList<Bloc>();
if(premierPassage == true) {
this.nombreBloc = 5 + rand.nextInt(30 - 5);
insererBlocList();
}
}
public ArrayList<Bloc> insererBlocList(){
premierPassage = false;
for(int i=0; i<nombreBloc; i++) {
Bloc bloc = new Bloc(false);
listeBlocRestant.add(bloc);
}
return listeBlocRestant;
}
public void paintComponent(Graphics2D g) {
Graphics2D g2 = (Graphics2D) g;
g2.fillRect(10, 20, this.largeur, this.hauteur);
}
I've got also a 3rd class where I call the GUI class :
public Optimisation() {
this.aff = new InterfaceGraphique();
}
And its in the above class where I need to do what I want.
I did not write in this what I want to do because I still don't know how to do it. Should I create a for each loop and take the list of blocks and for every blocks I want them to be print on the panel, with an x and y (of the fillRect) change between blocs ? I'm really lost, I tried to think about this yesterday but still no clue..
Cordially
I'm lost lol I do not understand everything in there since its with the click and so on
Well, the clicks are really not relevant to the painting concept.
The painting concept is you store the object you want to paint in an ArrayList. Then in the paintComponent() method you iterate through the ArrayList to paint each object.
In my example you have a method addRectangle(...) which adds one Rectangle object at a time. You can manually add a Rectangle by invoking this method without using a mouse. This allows you to add Rectangles of a different size/location/color.
For example you just change the code as follows:
private static void createAndShowGUI()
{
DrawingArea drawingArea = new DrawingArea();
drawingArea.addRectangle(new Rectangle(10, 10, 200, 100), Color.RED);
drawingArea.addRectangle(new Rectangle(210, 110, 20, 100), Color.BLUE);
Now the red rectangle will appear when you run the code.
The key points are:
you need a way to add the object you want to paint to your class
you then need to paint these objects in your paintComponent() method. You can't hardcode the painting the way you are currently doing it.
In your code your Bloc object will need to contain the information needed to paint the bloc.

Place holder text on a AutoCompleteField in blackberry

I have tp place a AutoCompleteField in one of my screen in Blackberry app. I have to show a place holder text to provide hint for user to enter the information.
Here is the below code of AutoCompleteField
BasicFilteredList filterList = new BasicFilteredList();
String[] address = { "T 115 Centro Galleria Shopping Centre, Cnr Old Collier and Walters Road Morley WA 1522",
"1423 SEAVIEW POINT POINT COOK VIC 2674",
"Lot 1498 Yarraman Road Wyndham Vale VIC 3795",
"Lot 3506 Witchmount Close Hillside VIC 4055",
"6 Paas Place Williamstown VIC 4233",
"Lot 99 14 James Close Sunbury VIC 4502",
"1 Charlotte Street Clayton South VIC 4779" };
filterList.addDataSet(1, address, "address", BasicFilteredList.COMPARISON_IGNORE_CASE);
AutoCompleteField autoCompleteField = new AutoCompleteField(filterList){
public void onSelect(Object selection, int SELECT_TRACKWHEEL_CLICK) {
ListField _list = getListField();
if (_list.getSelectedIndex() > -1) {
if(selectedText!=null){
BasicFilteredListResult result = (BasicFilteredListResult) selection;
selectedText.setText(result._object.toString());
}
}
}
};
add(autoCompleteField);
Anyone, please suggest me how could I implement the same.
Thanks.
You can use a similar technique to the one shown here for normal EditFields. Basically, you need to override the paint() method in an AutoCompleteField subclass. In paint(), you check and see if the field is empty, and if so, you manually draw the placeholder text you want.
The difference is that AutoCompleteField is a Manager with a BasicEditField inside of it. So, to draw the text properly, you need to figure out the x and y offsets of the edit field within the parent Manager (the AutoCompleteField).
So, replace your AutoCompleteField instance with an instance of this class:
private class CustomAutoCompleteField extends AutoCompleteField {
private int yOffset = 0;
private int xOffset = 0;
public CustomAutoCompleteField(BasicFilteredList filteredList) {
super(filteredList);
}
protected void paint(Graphics g) {
super.paint(g);
if (xOffset == 0) {
// initialize text offsets once
xOffset = getEditField().getContentLeft();
yOffset = getEditField().getContentTop();
}
String text = getEditField().getText();
if (text == null || text.length() == 0) {
int oldColor = g.getColor();
g.setColor(Color.GRAY);
g.drawText("enter text", xOffset, yOffset);
g.setColor(oldColor);
}
}
public void onSelect(Object selection, int SELECT_TRACKWHEEL_CLICK) {
ListField _list = getListField();
if (_list.getSelectedIndex() > -1) {
if(selectedText!=null){
BasicFilteredListResult result = (BasicFilteredListResult) selection;
selectedText.setText(result._object.toString());
}
}
}
}
I tested this on OS 5.0, with an instance that didn't have any margin or padding set. It's possible that with different layouts, you may need to adjust the logic for calculating the x and y offsets. But, the above code shows you the basic idea. Good luck.
Edit: the above code is presented with the caveat that your onSelect() method is clearly relying on code not shown. As is, the above code won't compile. I left onSelect() in there just to show that I'm essentially just replacing the anonymous class you originally had, and not doing anything different in your onSelect() method, as it's not directly related to the placeholder text issue.

Resize autocomplete field blackberry

I want to reduce the height of my autocomplete field.How to go about it
heres my code
HorizontalFieldManager hfm = new HorizontalFieldManager();
LabelField lbl = new LabelField(" Name: ");
final AutoCompleteField TextField1 = new AutoCompleteField(filterLst)
{
public int getPreferredWidth()
{
return Display.getWidth()/2;
}
public void sublayout(int maxWidth, int maxheight)
{
super.sublayout(getPreferredWidth(), getPreferredHeight());
setExtent(getPreferredWidth(), getPreferredHeight());
}
};
hfm.add(lbl);
hfm.add(TextField1);
add(hfm);
The picture below is how it looks. I want it to look the same size as my editfields that have been used for other labels.
Here's my code for editfield
//Add box next to field for containing input
HorizontalFieldManager hfm1 = new HorizontalFieldManager();
LabelField lbl1 = new LabelField(" Amount: ");
final EditField TextField2 = new EditField()
{
boolean _drawFocus = false;
protected void layout(int maxWidth, int maxHeight)
{
super.layout(Math.min(maxWidth, 300), Math.min(maxHeight, 30));
}
protected boolean keyChar(char ch, int status, int time)
{
if (CharacterUtilities.isDigit(ch) || (ch == Characters.BACKSPACE))
{
return super.keyChar(ch, status, time);
}
return true;
}
protected void drawFocus(Graphics graphics,boolean on)
{
_drawFocus = on;
super.drawFocus(graphics, on);
_drawFocus = false;
}
protected void paint(Graphics g)
{
if ( _drawFocus )
{
super.paint(g);
return;
}
g.clear();
g.drawRect(0,0, 50, 50);
int oldColor = g.getColor();
g.setColor(Color.WHITE);
g.fillRect(0, 0, this.getPreferredWidth(), this.getPreferredHeight());
g.setColor(oldColor);
g.drawRect(100, 100, 50, 50);
super.paint(g);
}
};
TextField2.setBorder(BorderFactory.createRoundedBorder(new XYEdges(6,6,6,6)));
hfm1.add(lbl1);
hfm1.add(TextField2);
add(hfm1);
I would like to have the size of autocompletefield used for name same as other fields.Please help.
Thanks
One thing that's probably causing you trouble is that EditField is what people normally think of as a Field. AutoCompleteField, however, is handled more like a Manager. It wants to be a Manager, of course, because it (probably) contains an EditField, but then will also contain another child Field which shows the autocomplete options dynamically.
(Non-Manager) Field and Manager subclasses handle layout a little differently, so I found that trying to fix this with the normal getPreferredHeight() and layout() and sublayout() didn't work that well for me.
So, what I did was twofold:
First, I tried to mimic the decoration of the default AutoCompleteField with your EditField subclasses. It's not perfect. If you want them to look exactly alike, you might need to write custom paint() methods for both. You stated the problem as simply wanting to resize the fields, so I thought that was good enough.
Second, since the AutoCompleteField seems to contain a child EditField (at least logically ... I'm not sure if it's implemented that way), I decided to try to get that EditField to choose its own size, in a way that matched the normal EditFields. To do that, I controlled all fields' height by simply setting the same Font on each.
My changes to your code:
final int fontSize = 24; // pick whatever you like here
final int pad = 2;
final int margin = 2;
I removed the code in your edit field's layout() method that was attempting to control height, since ... as I said, I didn't have success setting the autocomplete field's height in a similar way. I just changed your edit field's layout() to a very standard implementation:
final EditField TextField2 = new EditField()
{
boolean _drawFocus = false;
protected void layout(int maxWidth, int maxHeight)
{
super.layout(getPreferredWidth(), getPreferredHeight());
}
Then, I set the padding on your edit field, because it looks to me like AutoCompleteField uses a pad of 2 pixels (on a 5.0 Storm2). You may not care, for this UI, but it also appears to have a margin of 2 pixels.
TextField2.setPadding(pad, pad, pad, pad);
TextField2.setMargin(margin, margin, margin, margin);
Then, I set the same font for all your fields. It doesn't have to be the default font. Just make them all the same. This step is what seemed to dictate the visible size of the rounded rectangle field drawn by AutoCompleteField ... setting the font.
Font font = Font.getDefault().derive(Font.PLAIN, fontSize);
TextField1.setFont(font);
TextField2.setFont(font);
After that, the edit fields and autocomplete fields should be a consistent height. I tested this on a 5.0 9550. Since the pad and margin values were determined experimentally, I can totally believe that those values (e.g. 2 pixels) could change on different devices. You may have to experiment a bit.

How to repaint out of focus dialog without gaining its focus?

I made some menu and it is to update conmmon variables (for text on grid) then the out-of-focus dialog must repaint the grid. Here is the screenshot:
The main control panel is always at top position and 'Data Display' panel is always sitting behind it. When press a button on front panel, Data Display must update its grid. Currently, the common variable 0.4 on the grid is updated by adding listener and works fine. But the grid itself is not repainting anymore. How can I repaint the out-of-focus dialog in real time?
Here is the code of the front panel:
public class MainDisplayForm extends javax.swing.JFrame {
Storage st = new Storage();
DisplayForm dF = new DisplayForm();
....
public MainDisplayForm() {
initComponents();
Btn_IncreaseGain.addActionListener(new ButtonListener_IncreaseGain());
}
....
} //MainDisplayForm ends here.
class ButtonListener_IncreaseGain implements ActionListener {
DisplayForm dF = new DisplayForm();
Storage st = new Storage();
ButtonListener_IncreaseGain()
{
}
public void actionPerformed(ActionEvent e) {
st.iGain = 20;
dF.revalidate();
dF.repaint();
System.out.println("Testing");
}
}//Listener ends here.
Here is code of Data Display:
public void paint(Graphics g)
{
g2 = (Graphics2D) g;
paintComponents(g2);
//added numbers are for adjustment.
int x = this.jPanel1.getX()+8;
int y = this.jPanel1.getY()+30;
int width = this.jPanel1.getWidth()+19;
int height = this.jPanel1.getHeight()+40;
//labelling voltages
label0.setText(st.zero);
label1.setText(st.v1);
label2.setText(st.v2);
label3.setText(st.v3);
label4.setText(st.v4);
label5.setText(st.v3);
label6.setText(st.v4);
g2.setColor(Color.darkGray);
for(int i=x; i<width; i=i+80)
{
g2.drawLine(i, y, i, height);
}
int j = 0;
for(int i=y; i<height; i=i+80)
{
j++;
//st.iGain
g2.setColor(Color.orange);
if(j==1)
{
double k1 = st.iGain * 0.4;
st.v1 = Double.toString(k1);
g2.drawString(st.v1, x+5, y+10);
}
if(j==2)
{
double k2 = st.iGain * 0.3;
st.v2 = Double.toString(k2);
g2.drawString(st.v2, x+5, y+90);
}
g2.setColor(Color.DARK_GRAY);
g2.drawLine(x, i, width, i);
....
} //grid info is not completed yet.
Thanks,
Focus isn't the issue and has nothing to do with your current problem. The solution is to change the properties of the data grid by updating fields it contains via setter methods and calling repaint on the JComponent (perhaps a JPanel, or some other component that derives ultimately from JComponent) held by the data grid. The paintComponent method of this component should use its class fields to update what it draws.
You almost never paint in the paint method of a JComponent and certainly you don't want to draw directly into a top-level window. You also probably don't want to set text of JLabels, JTextFields, or any other JTextComponent. from within paint/paintComponent.
I can't see why your code is not working and can only guess that the likely cause of your problem is in code not shown.
Edit 1:
Just guessing, but you may have a problem of references. I notice that your listener class creates new DisplayForm and Storage objects:
DisplayForm dF = new DisplayForm();
Storage st = new Storage();
There's a good possibility that these objects are not the ones being displayed, especially if you create these objects elsewhere and display them. Again I'm just guessing since I don't see the rest of your code, but perhaps you should to pass references for these objects into the DisplayForm via constructor or setter method parameters.
Edit 2:
e.g.,
public void setDisplayForm(DisplayForm dF) {
this.dF = dF;
}
// same for Storage
And in the main program:
public MainDisplayForm() {
initComponents();
ButtonListener_IncreaseGain btnListenerIncreaseGain = new ButtonListener_IncreaseGain();
btnListenerIncreaseGain.setDisplayForm(....);
btnListenerIncreaseGain.setStorage(....);
Btn_IncreaseGain.addActionListener(btnListenerIncreaseGain);
}

JScrollPane getX() returing wrong value ?

I wish to place a small Jframe right above the Button, on ActionPerformed
I directly tried to get the X (getX()) and Y(getY()) co-ordinates of the JScrollPane in which the button is added, but it always seems to return wrong co-coordinates
values returned by jScrollPane1.getLocation()
java.awt.Point[x=10,y=170]
The above values are same independent on where I place the JScrollPane on the screen.
This works if I remove the JScrollPane and directly try to get the Jpanels co-ordinates!!
for example
private void showDialog() {
if (canShow) {
location = myButton.getLocationOnScreen();
int x = location.x;
int y = location.y;
dialog.setLocation(x - 466, y - 514);
if (!(dialog.isVisible())) {
Runnable doRun = new Runnable() {
#Override
public void run() {
dialog.setVisible(true);
//setFocusButton();
//another method that moving Focus to the desired JComponent
}
};
SwingUtilities.invokeLater(doRun);
}
}
}
This nice method will help you:
// Convert a coordinate relative to a component's bounds to screen coordinates
Point pt = new Point(component.getLocation());
SwingUtilities.convertPointToScreen(pt, component);
// pt is now the absolute screen coordinate of the component
Add: I didn't realise, but like mKorbel wrote, you can simply call
Point pt = component.getLocationOnScreen();
Since you want to spawn a new frame right above a given component, you want to get the screen coordinates of your component.
For this, you need to use the getLocationOnScreen() method of your component.
Here is a useful code snippet :
public void showFrameAboveCmp(Frame frame, Component cmp) {
Dimension size = cmp.getSize();
Point loc = cmp.getLocationOnScreen();
Dimension frameSize = frame.getSize();
loc.x += (size.width - frameSize.width)/2;
loc.y += (size.height - frameSize.height)/2;
frame.setBounds(loc.x, loc.y, frameSize.width, frameSize.height);
frame.setVisible(true);
}

Categories

Resources