GradientDrawable stroke outside only - java

I have created a custom button using this code:
Button goButton = (Button) findViewById(R.id.buttonStartTest);
View v = findViewById(R.id.buttonStartTest);
v.setBackground( new DrawableGradient(new int[] { btnColor,btnColor, 0xffffffff }, 110,10));
goButton.setText(getString(R.string.START_FORM));
And where the DrawableGradent looks like:
public class DrawableGradient extends GradientDrawable {
DrawableGradient(int[] colors, int cornerRadius,int strokeSize) {
super(Orientation.BOTTOM_TOP, colors);
try {
this.setShape(GradientDrawable.RECTANGLE);
this.setGradientType(GradientDrawable.LINEAR_GRADIENT);
this.setCornerRadius(cornerRadius);
int strokeColor = Color.argb(50, 0, 0, 0);
this.setStroke(strokeSize,strokeColor);
} catch (Exception e) {
e.printStackTrace();
}
}
}
This results in a button that looks like this:
This is what I want to get except that I want the stroke to only be on the outside of the button. How can I achieve this?
This is what the desired look is:
Thanks for your help! :)
/Daniel

Related

Android forEachIndexed() function on Java

Hey I'd like to ask if there is any way that I can use the Kotlins forEachIndexed() function for lists in Java? I searched everywhere but I couldn't find anything. I want to iterate over a list of ImageButtons and to each list item I want to set an Image from another list of bitmap image. So in Kotlin it would be:
buttons.forEachIndexed{index, button ->
button.setOnclickListener{
button.setImageResource(images[index])
}
}
The way I am iterating over buttons is
for(ImageButton button: buttons)
but I don't have any way to iterate over the indices. Can I somehow turn the Kotlin code above to Java?
Here is my code so far:pastebin.com/Rh9vcNbz
If you have the Kotlin stdlib in the project but are working on a Java file, you can use Kotlin's forEachIndexed from Java. It's not particularly pretty but it's doable:
import kotlin.collections.CollectionsKt;
...
CollectionsKt.forEachIndexed(list, (index, element) -> {
doSomething();
return Unit.INSTANCE;
});
I work with Java and Kotlin for some years now and sadly I think that there is nothing in Java (atleast which is standard) that can deliver you something like Kotlin does with its forEachIndexed.
I mean if you look at the implementation of the "forEachIndexed"...
It is nothing more then this:
var index = 0
for (item in this) action(checkIndexOverflow(index++), item)
it basically creates an int variable for you, and increments it, while iterating over the List and invoking your Lambda.
If you still want something similar, which is still "hacky" - I wrote something for you, not that I want to say that it is perfect but does the job - and it is still generic.
New Classes:
public interface IndexedAction<T> {
void action(T item, int index);
}
public class ExtendedArrayList<T> extends ArrayList<T> {
public void forEachIndexed(IndexedAction<T> indexedAction) {
int i = 0;
for (T element : this) {
indexedAction.action(element, i);
i++;
}
}
}
Usage:
#Test // Robolectric Unit Test
public void myTest() {
ExtendedArrayList<Bitmap> bitmapArray = new ExtendedArrayList<>();
ExtendedArrayList<ImageButton> buttons = new ExtendedArrayList<>();
Application context = RuntimeEnvironment.application;
int width = 200;
int height = 100;
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmapArray.add(bitmap);
bitmapArray.add(bitmap);
bitmapArray.add(bitmap);
bitmapArray.add(bitmap);
Collections.shuffle(bitmapArray);
ImageButton button1 = new ImageButton(context);
ImageButton button2 = new ImageButton(context);
ImageButton button3 = new ImageButton(context);
ImageButton button4 = new ImageButton(context);
buttons.add(button1);
buttons.add(button2);
buttons.add(button3);
buttons.add(button4);
buttons.forEachIndexed((button, index) ->
button.setImageBitmap(bitmapArray.get(index)));
}

How to check if all textview text is visible in scrollview

I tried checking if the height of the text in the textview is larger than the scroll view to handle situations where the user does not have to scroll to read the text but nothing online is working for me.
I tried solutions online but those don't work either
if (binding.wvTermsAndCond.getLocalVisibleRect(scrollBounds)) {
// imageView is within the visible window
Utils.showToast(mContext, "View is within the visible window", true);
} else {
// imageView is not within the visible window
Utils.showToast(mContext, "View is not within the visible window", true);
}
The not visible block was getting called
if you want to check if a view is visible or not you can use these methods:
public static boolean isVisible(final View view) {
if (view == null) {
return false;
}
if (!view.isShown()) {
return false;
}
final Rect actualPosition = new Rect();
view.getGlobalVisibleRect(actualPosition);
final Rect screen = new Rect(0, 0, getScreenWidth(), getScreenHeight());
return actualPosition.intersect(screen);
}
public static int getScreenWidth() {
return Resources.getSystem().getDisplayMetrics().widthPixels;
}
public static int getScreenHeight() {
return Resources.getSystem().getDisplayMetrics().heightPixels;
}

Flickering XYImageAnnotation on JFreeChart with timer

I have difficulties drawing an image on a JFreeChart - XYLineChart. The main problem is the x and y coordinates of the annotation is updated dynamically in real time.So with my code adding the annotation and clearing it for the new one to be drawn causes flickering which is annoying for the user.
I have checked some examples of flickering problems on JAVA using update() , paint () or repaint() methods using graphics but seems not implementable on a JFreeChart.
Do you have any ideas how to get rid of the flicker or a workaround to use one bufferedImage on the JFreeChart instead of an annotation ?
To be more specific here is the drawn line and the image :
Screenshot
So this cross hair (as the buffered image) should go on the plot line up and down with the updated values of x and y axis.But this motion causes the flickering unfortunately.
Here is the part of my code where I draw the image - I cannot provide SSCCE I guess since there are more than 15 classes and 5k of written code :
// After a button clicked on panel
SomeButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
// The chart and XYPlot is already drawn at this point
// Reading the image
try {
myPicture = ImageIO
.read(new File("\\\\Users2\\blabla\\Data\\MyPictures\\x.png"));
} catch (IOException e) {
e.printStackTrace();
}
// Setting up a timer
timer2 = new java.util.Timer();
Object source = event.getSource();
if (source == SomeButton) {
// Setting up a task
task2 = new java.util.TimerTask() {
#Override
public void run() {
double x1;
double y1;
try {
// Getting different x and y values from a microcontroller instantaneously
if (microContConnected()) {
x1 = microCont.getX();
y1 = microCont.getY();
// creating the annotation
XYImageAnnotation ImageAnn = new XYImageAnnotation(x1, y1, myPicture);
// Here is the drawing and clearing made !
plot.addAnnotation(ImageAnn);
pause(50);
plot.clearAnnotations();
}
} catch (SerialPortException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
timer2.scheduleAtFixedRate(task2, 50, 50);
}
}
});
It seems I found a solution myself ; instead of adding the image to plot I use the renderer and there is no pause function between adding and removing the picture with new coordinates.. also sequence of adding and removed are reversed. Surprising for me to work this way I must say. There is no flickering left; it's as smooth as a clipped graphics or double buffered. :) Here is the new code :
// renderer
final XYLineAndShapeRenderer renderer = (XYLineAndShapeRenderer) plot.getRenderer();
// Reading the image
try {
myPicture = ImageIO.read(new File("\\\\Users2\\blabla\\Data\\MyPictures\\x.png"));
} catch (IOException e) {
e.printStackTrace();
}
// Setting up a timer
timer2 = new java.util.Timer();
Object source = event.getSource();
if (source == someButton) {
task2 = new java.util.TimerTask() {
#Override
public void run() {
if (check == true) {
if (microContConnected()) {
x1 = microCont.getX();
y1 = microCont.getY();
renderer.removeAnnotations();
XYImageAnnotation img2 = new XYImageAnnotation(
x1, y1, myPicture);
renderer.addAnnotation(img2,
Layer.FOREGROUND);
}
}
}
};
timer2.scheduleAtFixedRate(task2, 50, 50);
}

LWUIT Painter : How to make an image the background?

I am trying to use Painter to make a certain jpg become my background.
mapScreen = new Form("Map");
try
{
Image image = Image.createImage("/res/try.jpg");
map = new Map(image);
mapScreen.addComponent(map);
} catch (Exception e)
{
System.out.print("Error\n\n"+e.getMessage());
mapScreen.addComponent(new Label(e.getMessage()));
}
And for the map class,
public Map(Image image)
{
this.mapImage = image;
painter = new Painter()
{
public void paint(Graphics g, Rectangle clippingRect)
{
g.clipRect(0, 0, getWidth(), getHeight());
g.drawImage(mapImage, getX(), getY());
}
};
}
public void initComponent()
{
setX(0);
setY(0);
getSelectedStyle().setBgTransparency(0);
getSelectedStyle().setBgPainter(painter);
getUnselectedStyle().setBgTransparency(0);
getUnselectedStyle().setBgPainter(painter);
}
The problem with this is that the image doesn't show up at all and when I try to debug, It doesn't even enter the paint(Graphics g, Rectangle clippingRect)...
The code
try
{
Image image = Image.createImage("/res/try.jpg");
map = new Map(image);
mapScreen.addComponent(map);
}
is successful.
Can anyone tell me how to do it properly?
And also, if anyone know how to do panning on an image larger than the size of the screen, Can you help me with that also? Thanks.
Use setBgTransparency to 255 and don't call the clipRect method.
You can look at the bg painter code within Component.java which is pretty flexible.

how to get images into blackberry and set an onClick listener?

I'm rather new to programming Blackberries and was wondering if anybody knows of a tutorial or a snippet about how to load an image into the screen and set an onClick listener to it?
edit, got this far:
ButtonField btf1 = new ButtonField("Fine!");
ButtonField btf2 = new ButtonField("Great!");
RichTextField rtf = new RichTextField("HELLO, HOW ARE YOU?");
Bitmap LOGO = Bitmap.getBitmapResource("1.png");
BitmapField LogoBmpField = new BitmapField(LOGO);
HelloWorldScreen()
{
setTitle("My First App");
add(rtf);
add(btf1);
add(btf2);
add(LogoBmpField);
}
Thanks!
edit: by the way, how should interfaces be made for blackberry? simply by
ButtonField btf1 = new ButtonField("Fine!");
add(btf1);
Or is there some more visible way, such as in XML for android?
One more thing, how to I change or set properties of some object. Say I want to change the title of my button- btf1.(expecting list of available properties to appear ) doesn't give anything.
Place your image in your res folder and try this;
Bitmap bmpLogo = Bitmap.getBitmapResource("yourImage.jpg");
BitmapField logo = new BitmapField(bmpLogo){
protected boolean trackwheelClick(int status, int time)
{
// Your onclick code here
return true;
}
};
add(logo);
1) You need to make your BitmapField focusable.
I just tried this:
BitmapField LogoBmpField = new BitmapField(LOGO, BitmapField.FOCUSABLE) {
protected boolean trackwheelClick(int status, int time) {
System.out.println(" -- You clicked me! ");
return true;
}
};
and it seems to work.
2) And to change the text on your button use
setLabel()
btf1.setLabel("new button text");
public class MyScreen extends MainScreen {
public LanguageSelector() {
Bitmap logoBitmap = Bitmap.getBitmapResource("normalarabflag.png");
BitmapField LogoBmpField = new BitmapField(logoBitmap, BitmapField.FOCUSABLE | Field.FIELD_HCENTER) {
protected boolean navigationClick(int status, int time) {
System.out.println(" -- You clicked me! ");
UiApplication.getUiApplication().pushScreen(new SecoundScreen());
Dialog.alert("Load Complete");
return true;
}
};
LabelField labelfield = new LabelField("Arabic ",Field.FIELD_HCENTER|LabelField.FOCUSABLE);
VerticalFieldManager vrt=new VerticalFieldManager(USE_ALL_WIDTH) {
protected void sublayout(int maxWidth, int maxHeight) {
super.sublayout(Display.getWidth(),Display.getHeight());
setExtent(Display.getWidth(),Display.getHeight());
}
};
Font f=labelfield.getFont();
int hight1=f.getAdvance(labelfield.getText());
int k=labelfield.getPreferredHeight();
int number=hight1/Display.getWidth()+1;
int hight2=logoBitmap.getHeight();
int padding=(Display.getHeight()-((number*k)+hight2))/2;
if(padding>0) {
LogoBmpField.setPadding(padding,0,0,0);
}
vrt.add(LogoBmpField);
vrt.add(labelfield);
add(vrt);
}
}

Categories