How can I draw a solid square in BlackBerry? - java

I'm making a BlackBerry OS 6+ application and I need to draw a solid square of a specific color (given at runtime) but it should be add-able to a VerticalFieldManager. So I think custom-drawing using a Graphics object is not an option.
I already tried setting the background color of a LabelField to the color I want and adding that LabelField to the VerticalFieldManager. To get the square-shaped appearance, I tried overriding the getPreferredWidth() and getPreferredHeight of LabelField to return a higher value (eg: 150). But although the width was correctly displayed, the height stayed the same no matter what value I returned.
So is there any way I can achieve this? In summary, what I want is:
A solid square-shaped block of color (color decided at runtime).
Which should be added to a VerticalFieldManager.
Thanks in advance!

try this code , Pass in the color in the constructor.
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Font;
import net.rim.device.api.ui.Graphics;
public class CustomField extends Field
{
private int backgroundColour;
private int fieldWidth;
private int fieldHeight;
private int padding = 8;
public CustomField(int color)
{
super(Field.FOCUSABLE);
fieldHeight = 100;
fieldWidth = 100;
this.setPadding(2, 2, 2, 2);
this.backgroundColour=color;
}
public int getPreferredWidth()
{
return fieldWidth;
}
public int getPreferredHeight()
{
return fieldHeight;
}
protected void layout(int arg0, int arg1)
{
setExtent(getPreferredWidth(), getPreferredHeight());
}
protected void drawFocus(Graphics graphics, boolean on)
{
}
protected void paint(Graphics graphics)
{
graphics.setColor(backgroundColour);
graphics.fillRect(0, 0, fieldWidth, fieldHeight);
}
}

VerticalFieldManager vfm = new VerticalFieldManager();
Field f = new Field() {
protected void paint(Graphics graphics) {
graphics.setBackgroundColor(Color.RED);
graphics.clear();
graphics.drawRect(10, 10, 100, 100);
graphics.fillRect(10, 10, 100, 100);
}
protected void layout(int width, int height) {
// TODO Auto-generated method stub
setExtent(200, 200);
}
};
vfm.add(f);
add(vfm);

Related

Weird issue updating a JLabel on JSlider change

Huy guys, I have a weird problem.
I'm kinda new to swing and java applications.
I'm trying to make a custom UI jslider that changes a jlabel text when you move the thumb.
My problem is: when I use the addChangeListener(), it creates a weird glitch when moving the thumb.
If I don't use it, it works perfectly fine.
How can I update the JLabel without using the change listener or how can I fix this graphic bug?
Most of this code comes from stackoverflow since I don't know much about painting components.
See pictures at the button to better understand the problem
Thanks!
The code in my jpanel
JSlider slider = new JSlider(SwingConstants.HORIZONTAL, 1, 10, 1) {
#Override
public void updateUI() {
setUI(new CustomSliderUI(this));
}
};
// If I comment this line the visual glitch is gone when moving the thumb, but the value doesnt update
slider.addChangeListener((event) -> RAM_LABEL.setText(slider.getValue() + " Gb"));
slider.setMinorTickSpacing(1);
slider.setMajorTickSpacing(10);
slider.setSnapToTicks(true);
slider.setBounds(96, 317, 300, 35);
slider.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
slider.setOpaque(false);
this.add(slider);
The custom slider ui class
private static class CustomSliderUI extends BasicSliderUI
{
private static final int TRACK_HEIGHT = 8;
private static final int TRACK_ARC = 5;
private static final Dimension THUMB_SIZE = new Dimension(22, 20);
private final RoundRectangle2D.Float trackShape = new RoundRectangle2D.Float();
private final Image knob;
public CustomSliderUI(final JSlider b)
{
super(b);
knob = Swinger.getResource("knob.png");
}
#Override
protected void calculateTrackRect() {
super.calculateTrackRect();
trackRect.y = trackRect.y + (trackRect.height - TRACK_HEIGHT) / 2;
trackRect.height = TRACK_HEIGHT;
trackShape.setRoundRect(trackRect.x, trackRect.y, trackRect.width, trackRect.height, TRACK_ARC, TRACK_ARC);
}
#Override
protected void calculateThumbLocation() {
super.calculateThumbLocation();
thumbRect.y = trackRect.y + (trackRect.height - thumbRect.height) / 2;
}
#Override
protected Dimension getThumbSize() {
return THUMB_SIZE;
}
#Override
public void paint(final Graphics g, final JComponent c) {
((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
super.paint(g, c);
}
#Override
public void paintTrack(final Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Shape clip = g2.getClip();
boolean inverted = slider.getInverted();
// Paint shadow.
g2.setColor(new Color(170, 170 ,170));
g2.fill(trackShape);
// Paint track background.
g2.setColor(new Color(200, 200 ,200));
g2.setClip(trackShape);
trackShape.y += 1;
g2.fill(trackShape);
trackShape.y = trackRect.y;
g2.setClip(clip);
// Paint selected track.
boolean ltr = slider.getComponentOrientation().isLeftToRight();
if (ltr) inverted = !inverted;
int thumbPos = thumbRect.x + thumbRect.width / 2;
if (inverted) {
g2.clipRect(0, 0, thumbPos, slider.getHeight());
} else {
g2.clipRect(thumbPos, 0, slider.getWidth() - thumbPos, slider.getHeight());
}
g2.setColor(Swinger.getTransparentWhite(0));
g2.fill(trackShape);
g2.setClip(clip);
}
#Override
public void paintThumb(final Graphics g)
{
g.drawImage(knob, thumbRect.x, thumbRect.y, null);
}
#Override
public void paintFocus(final Graphics g) {}
}
Visual glitch when you are moving the cursor, as soon as you stop pressing the mouse it goes back to normal
Regular cursor / when I move it without the change listener
Solved. I went with drawing my own background it was simplier.
private static class CustomSliderUI extends BasicSliderUI
{
private static final Dimension THUMB_SIZE = new Dimension(22, 20);
private final Image thumb, background;
private final JSlider slider;
public CustomSliderUI(final JSlider b)
{
super(b);
slider = b;
thumb = Swinger.getResource("thumb.png");
background = Swinger.getResource("slider.png");
}
#Override
protected Dimension getThumbSize() {
return THUMB_SIZE;
}
#Override
public void paintTrack(final Graphics g) {
g.drawImage(background, 10, 11, 280, 10, null);
}
#Override
public void paintThumb(final Graphics g)
{
g.drawImage(thumb, thumbRect.x, thumbRect.y, null);
slider.repaint();
}
#Override
public void paintFocus(final Graphics g) {}
}
JSlider slider = new JSlider(SwingConstants.HORIZONTAL, 1, 10, 1) {
#Override
public void updateUI() {
setUI(new CustomSliderUI(this));
}
};
slider.addChangeListener((event) -> RAM_LABEL.setText(slider.getValue() + " Gb"));
slider.setBounds(96, 317, 300, 35);
slider.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
slider.setOpaque(false);
this.add(slider);

BlackBerry - How to properly handle a TAP/CLICK in a custom Manager

I need to set up a click/tap event for a custom Manager.
The Manager contains a couple of elements, but I need that the whole
Manager respond to the event, so if the user taps/clicks any element
inside the Manager, the event handler should be called too.
What I have done is to attach a changeListener to a NullField that takes all width and height, but the fieldChanged method is never called
public class TestManager extends Manager{
private BitmapField _icon;
private LabelField _lblTitle;
private NullField nullField;
public TestManager(Bitmap pIcon){
super(Manager.FOCUSABLE);
_icon = new BitmapField(pIcon);
_lblTitle = new LabelField("This is the title");
nullField = new NullField(NullField.FOCUSABLE);
add(_icon);
add(_lblTitle);
add(nullField);
nullField.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
doSomething();
}
});
}
public void doSomething(){
System.out.println("do something!!");
}
public void paint(Graphics graphics)
{
graphics.setColor(Color.DELIMITER_COLOR);
graphics.fillRect(0, 20, Display.getWidth(), 50);
super.paint(graphics);
}
protected void paintBackground(Graphics arg0) {
arg0.setColor(Color.LIGHTGRAY);
arg0.fillRect(0, 0, Display.getWidth(), Display.getHeight());
super.paint(arg0);
}
protected void sublayout(int width, int height) {
setPositionChild(_icon, UIFactory.getBestX(10), UIFactory.getBestX(8));
setPositionChild(_lblTitle, UIFactory.getBestX(60), _topMarginTitle!=0?UIFactory.getBestX(_topMarginTitle):UIFactory.getBestX(15));
setPositionChild(nullField, 0, 0);
layoutChild(_icon, width, UIFactory.getBestX(50));
layoutChild(_lblTitle, width, UIFactory.getBestX(50));
layoutChild(nullField, width, height);
setExtent(width, height);
}
protected boolean navigationClick(int status, int time){
invalidate();
doSomething();
return super.navigationClick(status, time);
}
}
How should I make this whole Manager to respond a click/tap?
I'm using the API 5.0
Thanks in advance!
Question was also asked in BB forums, and I have responded there:
BlackBerry-How-to-properly-handle-a-TAP-CLICK-in-a-custom
Further to this, here is a solution to the problem:
public class BaseTouchManager extends Manager {
private FieldChangeListener _callBack;
public BaseTouchManager(FieldChangeListener pCallBack) {
super(0);
_callBack = pCallBack;
setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
_callBack.fieldChanged(field, context);
}
});
add(new NullField(Field.FOCUSABLE));
}
protected void sublayout(int width, int height) {
setExtent(Display.getHeight()/2, 100);
}
protected boolean navigationClick(int status, int time) {
fieldChangeNotify(1);
return true;
}
public void paint(Graphics graphics) {
if(_callBack!=null){
if(isFocus())
graphics.setColor(Color.LIGHTBLUE);
else
graphics.setColor(Color.WHITE);
graphics.fillRect(this.getWidth() - 10,
this.getHeight() - 10,
10, 10);
}
super.paint(graphics);
}
}
The original poster actually suggested a different solution, review the BB forum post for more.

Margin for Custom JButton - Java

I've created a custom button for my application by extending Jbutton, and I've got it to paint the way I want, but for some reason, even though I call setMargin() in the constructor, the buttons have 0 margin, like so:
Is there something I'm doing wrong in my code? How is it that standard JButtons have margins, but my custom buttons don't?
The java code for my button:
public class CToolbarButton extends JButton
{
private static final Dimension SIZE = new Dimension(48, 48);
private static final int MARGIN_VAL = 50;
private static final Insets MARGIN = new Insets(MARGIN_VAL, MARGIN_VAL, MARGIN_VAL, MARGIN_VAL);
private static final Color FILL_NORM = Color.GRAY;
private static final Color FILL_ACTIVE = new Color(FILL_NORM.getRed()-25, FILL_NORM.getGreen()-25, FILL_NORM.getBlue()-25);
private static final Color BORDER_NORM = Color.BLACK;
private static final Color BORDER_ACTIVE = Color.YELLOW;
public CToolbarButton()
{
super();
setContentAreaFilled(false);
setFocusable(false);
setMargin(MARGIN);
}
#Override
public void paintComponent(Graphics g)
{
if (getModel().isArmed())
{
g.setColor(FILL_ACTIVE);
}
else
{
g.setColor(FILL_NORM);
}
g.fillRect(0, 0, getWidth(), getHeight());
}
#Override
public void paintBorder(Graphics g)
{
if (getModel().isArmed())
{
g.setColor(BORDER_ACTIVE);
}
else
{
g.setColor(BORDER_NORM);
}
g.drawRect(0, 0, getWidth(), getHeight());
}
#Override
public boolean contains(int x, int y)
{
return (x >= 0 &&
x <= getWidth() &&
y >= 0 &&
y <= getHeight());
}
#Override
public Dimension getPreferredSize()
{
return SIZE;
}
#Override
public Dimension getMinimumSize()
{
return SIZE;
}
#Override
public Dimension getMaximumSize()
{
return SIZE;
}
}
Instead of trying to override the paint method for the button, I'm just going to use images to simulate different looks for buttons instead.

Clicking on a JPanel to draw shapes

I have a JFrame containing 3 JPanels; Options, menu, canvas. In options there are a number of JButtons representing shapes. The aim is to click on the JButton of a shape e.g. rectangle, then click anywhere on the canvas and the shape will be drawn there.
For some reason, the shape does not always get drawn, it is only drawn when I click somewhere in the top left area of the canvas. Also the shape seems to randomly change size depending on where I click.
Here are some of my code snippets, it's probably a small error but I just can't seem to find it.
Shape:
public class Shape extends JPanel {
protected int xLocation;
protected int yLocation;
protected int numberOfSides;
protected String areaInfo;
protected String perimeterInfo;
public int getXLocation() {
return xLocation;
}
public void setXLocation(int xLocation) {
this.xLocation = xLocation;
}
public int getYLocation() {
return yLocation;
}
public void setYLocation(int yLocation) {
this.yLocation = yLocation;
}
public int getNumberOfSides() {
return numberOfSides;
}
public Shape(int xLocation, int yLocation, int numberOfSides) {
this.xLocation = xLocation;
this.yLocation = yLocation;
this.numberOfSides = numberOfSides;
}
}
Rectangle:
import java.awt.Color;
import java.awt.Graphics;
public class Rectangle extends Shape {
private int width;
private int height;
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public Rectangle(int xLocation, int yLocation, int width, int height ) {
super(xLocation, yLocation, 4);
this.width = width;
this.height = height;
this.areaInfo = "Multiply width * height";
this.perimeterInfo = "Add the lengths of each side";
}
public void paint(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(xLocation, yLocation, width, height);
}
}
Canvas:
public class DrawingCanvas extends JPanel implements Serializable{
private ArrayList<Shape> shapeList;
OptionsPanel options;
public void addShape(Shape shape){
shapeList.add(shape);
this.add(shape);
this.repaint();
}
public DrawingCanvas(){
shapeList = new ArrayList<Shape>();
}
}
Frame:
public class DrawingFrame extends JFrame implements MouseListener, MouseMotionListener {
private OptionsPanel options;
private DrawingCanvas canvas;
private MenuBar menu;
Shape s; //shape to be manipulated
public DrawingFrame(){
options = new OptionsPanel();
canvas = new DrawingCanvas();
menu = new MenuBar();
//options.setBounds(0, 0, 100, 500);
options.setBackground(Color.GREEN);
canvas.setBackground(Color.yellow);
menu.setSize(1000,200);
menu.setBackground(Color.magenta);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(1000,500);
this.setTitle("Drawing Application");
this.setLayout(new BorderLayout());
this.getContentPane().add(options, BorderLayout.WEST);
this.getContentPane().add(canvas, BorderLayout.CENTER);
this.getContentPane().add(menu, BorderLayout.PAGE_START);
this.setVisible(true);
options.createRectangleButton.addMouseListener(this);
options.createSquareButton.addMouseListener(this);
options.createCircleButton.addMouseListener(this);
options.createTriangleButton.addMouseListener(this);
options.clearButton.addMouseListener(this);
canvas.addMouseListener(this);
canvas.addMouseMotionListener(this);
}
#Override
public void mouseClicked(MouseEvent e) {
boolean createShape = true;
if(e.getSource().equals(options.createRectangleButton)){
createShape = true;
s = new Rectangle(50,50,400,200);
s.addMouseListener(this);
s.addMouseMotionListener(this);
}
if (e.getSource().equals(canvas) && createShape == true){
s.setXLocation(e.getX());
s.setYLocation(e.getY());
createShape = false;
canvas.addShape(s);
}
Absent a complete example, it's hard to say. I'd expect your DrawingCanvas to override paintComponent() in order to render the accumulated Shape instances in shapeList. You might compare your approach to that shown in GaphPanel, cited here.
The code you provided is not complete, but anyway the problem is in your mouseClicked method, if you change your second if to something like the following for example:
if (e.getSource().equals(canvas) && createShape == true){
int x = e.getX();
int y = e.getY();
s = new Rectangle(x,y,x+50,y+50);
canvas.addShape(s);
}
then a rectangle of width & height 50 will be painted whenever you click on the canvas, depending on your x, y location (you could change the fixed width/height by using a variable based on user input). Also, I'm not sure what you're trying to do in your first if section where you're adding a MouseListener to a newly created shape that is not added to the canvas, I guess there's something else you want to do...
I had to overwrite the canvas class' paint method; call super.paint in the canvas class and repaint each shape individually
public void paint(Graphics g){
super.paint(g);
for(int i=0;i<shapeList.size();i++){
((Shape)shapeList.get(i)).paint(g);
}
}

Reduce size of EditField

I am creating five EditFields with corresponding label fields.
The EditFields use the full width of the screen but I need only want them to use a particular width.
try this code:-
BasicEditField bef = new BasicEditField("BBDeveloper","")
{
public int getPreferredHeight()
{
return 30;
}
public int getPreferredWidth()
{
return 100;
}
public void layout(int width, int height)
{
setExtent(getPreferredWidth(), getPreferredHeight());
super.layout(getPreferredWidth(), getPreferredHeight());
}
};
alter the getPreferredWidth() and getpreferredHeight() returning values... and see if this help you out....
set the change font bellow the rewritable methods like these:
lbDesc = new LabelField(title, LabelField.USE_ALL_WIDTH)
{
protected void paint(Graphics g)
{
//Font font = Font.getDefault().derive(Font.PLAIN,6,Ui.UNITS_pt);
//g.setFont(font);
g.setColor(Color.BLACK);
invalidate();
super.paint(g);
}
};
Font font = Font.getDefault().derive(Font.PLAIN,6,Ui.UNITS_pt);
lbDesc.setFont(font);

Categories