When I was using absolute layout my objects where appearing but I couldnt move them so I changed the layout to null and now my objects dont even appear. Please help.
Havent tried much, not sure what to try.
try {
enemies = new LinkedList<>();
frame = new JFrame();
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setLayout(null);
frame.getContentPane().setBackground(Color.black);
frame.setPreferredSize(new Dimension(800, 800));
ActionListener spawnEnemies = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
spawnEnemies();
}
};
ActionListener moveEnemies = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
moveEnemies();
}
};
spawner = new Timer(50000, spawnEnemies);
spawner.start();
mover = new Timer(10, moveEnemies);
mover.start();
addKeyListener(new KeyInput(this));
player = new PlayerObj("white", 399, 399, frame);
player.setPreferredSize(new Dimension(50, 50));
//AddActionEvent, Keylogging, OnbuttonPress, Autogenerating enemies, timers.
frame.getContentPane().add(player);
spawnEnemies();
frame.revalidate();
frame.repaint();
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Game.class.getName()).log(Level.SEVERE, null, ex);
}
I am not sure what do you want with the code, but I assume you want to display enemies/players at specified locations on screen. I personally don't decommend using Components added to a JFrame to display that. This means with no layout, the JFrame will have no idea how to place these objects.
Here is an other way that will solve your problem, howewer it is a totally different approach.
You have to create a JFrame, and set its content pane to a new JPanel(recommended to extend your class from JPanel and adding itself to the JFrame, it can make things easier).
Then, you override the repaint method, by creating the following:
protected void paintComponent(Graphics g){
}
When you call the repaint() method, it will run this code. So inside here, you can paint whatewer and wherever you want (inside you JPanel). And you don't have to mess with the Layout, just leave it as default.
Examples for painting:
g.setColor(Color.blue);
g.fillRect(50,50,120,120);
//
g.drawImage(yourImage,100,100,this);
Related
Image1
Image2
I wanna make "btn_34" in [image2] to move "game39" class if user clicked "btn_21_2" in [image1]. If user didn't click "btn_21_2", Wanna make "btn_34" to move "game30". Which thing should I add or change in these pic?
Please post code and not images of code.
3 options: Quick, Standard, Best.
1-> Place public static boolean button21Flag = false; in your game17.class and when they click button btn_21_2 change it to true. When you get to btn_34.
if(game17.button21Flag)
intent = new Intent(game26.class,game39.class)
else
intent = new Intent(game26.class,game30.class)
2 -> Place an Extra into the Intent when btn_21_2 is clicked. And keep passing it, until you need it in btn_34.
btn_21_2.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
Intent intent = new Intent(game17.class,game18.class);
intent.putExtra("button21Flag", true);
startActivity(intent);
}
});
// in btn_34 getIntent.getBooleanExtra("button21Flag", false);
3-> This solution is based on how complex and convoluted your code will get, if you keep approaching it this way.
Create a singleton called GameState and have it keep track of the game state. Anything you would like to keep track of should go in here and when you get to the point where you need it you can access it anywhere via a static context.
(EDIT) To respond to your answer.
public static boolean game17Flag = false;
btn_21_2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
game17Flag = true;
Intent intent = new Intent(game17.this, game18.class);
startActivity(intent);
}
});
//Remove this completely
{
if (btn_21_2.isPressed()) {
game17Flag = true;
}
}
I am in need of some help making custom sliders, sort of like the ones you would use for volume buttons. I have one but it's not multi usable; as soon as I add more than one the ones before stop working, and I don't think I can use local variables because I need to use event listeners for the scrubber to slide.
All I am asking is if someone can please put a code for a multi usable slider with explanation on how it works so I can learn from it. I can show the code I am using right now but its probably useless.
public function createSlider(x:Number, y:Number, parent:DisplayObjectContainer) : void {
this.slider = new Sprite();
this.slider.graphics.beginFill(0xFFFFFF);
this.slider.graphics.drawCircle(x, y, 7);
this.slider.graphics.endFill();
this.bar = makeRoundedRect(x - 6, y - 6, 100, 11, 0xCCCCCC, 1, [10, 10, 10, 10]);
parent.addChild(bar);
parent.addChild(slider);
this.slider.addEventListener(MouseEvent.MOUSE_OVER, sliderHover);
}
private function sliderHover(e:MouseEvent) : void
{
this.slider.addEventListener(MouseEvent.MOUSE_DOWN, sliderDown);
}
private function sliderDown(e:MouseEvent) : void {
this.slider.addEventListener(MouseEvent.MOUSE_MOVE, sliderMove);
this.slider.addEventListener(MouseEvent.MOUSE_UP, sliderDone);
this.slider.addEventListener(MouseEvent.MOUSE_OUT, sliderDone);
}
private function sliderMove(e:MouseEvent) : void {
this.slider.addEventListener(MouseEvent.MOUSE_DOWN, sliderDown);
this.slider.removeEventListener(MouseEvent.MOUSE_MOVE, sliderMove);
this.slider.startDrag(false, new Rectangle(0, slider.y, 90, 0));
}
private function sliderDone(e:MouseEvent) : void {
this.temp_mouseCurX = Math.abs(this.slider.x + 10);
trace(this.temp_mouseCurX);
this.slider.stopDrag();
}
It's using a private variable which I know shouldn't be good for what I am trying to do.
You should try using e.currentTarget. instead of this.slider.
I'm trying to refresh Canvas on DoubleTap in android. I use GestureDetector in custom View.
final GestureDetector mDetector = new GestureDetector(
getContext(), new GestureDetector.OnGestureListener() {
#Override
public boolean onDoubleTap(MotionEvent e) {
invalidate();
return true;
}
}
But I'm getting the error
The method onDoubleTap(MotionEvent) of type new
GestureDetector.OnGestureListener(){} must override or implement a
supertype method
with
Remove '#Override' annotation
solution. I remove override and get this warning
The method onDoubleTap(MotionEvent) from the type new
GestureDetector.OnGestureListener() {} is never used locally.
Then I tried to test whether this works and made a function to change TextView string whenever I DoubleTap. Nothing happens.
I also looked at GestureDetector Reference for explanations, but they don't even have DoubleTap there, which everybody uses. What should I do?
try this
final GestureDetector mDetector = new GestureDetector(getContext(), new GestureDetector.SimpleOnGestureListener {
#Override
public boolean onDown(MotionEvent e) {
return true;
}
#Override
public boolean onDoubleTap(MotionEvent e) {
return true;
}
});
For the ones, who were wondering how to set it also to the corresponding view:
final GestureDetector gDetector = new GestureDetector(getBaseContext(), new GestureDetector.SimpleOnGestureListener() {
#Override
public boolean onDown(MotionEvent e) {
return true;
}
#Override
public boolean onDoubleTap(MotionEvent e) {
doIt();
return true;
}
});
// Set it to the view
mButton.setOnTouchListener((v, event) -> gDetector.onTouchEvent(event));
My approach to this problem was different since I needed to perform something for the onClick listener as well, and also it was in a list view, so I needed to know what was the item content.
here is my approach using kotlin Job:
At the top of the class I've declared something like this:
private var doubleTapTimerJob: Job = Job()
private var clickedViewItem: CartViewItem? = null
val DOUBLE_TAP_DELAY = 200L
where CartViewItem is the model that is used in the list.
and this is my onClickListener logic:
if (clickedViewItem == null || clickedViewItem != cartViewItem) {
doubleTapTimerJob.cancel()
doubleTapTimerJob = lifecycleScope.launch {
delay(DOUBLE_TAP_DELAY)
clickedViewItem = null
}
clickedViewItem = cartViewItem
onClicked(cartViewItem)
} else {
onDoubleClicked(cartViewItem)
clickedViewItem = null
doubleTapTimerJob.cancel()
}
here I wait for 200 milliseconds for the second tap, and if it didn't happen, I will make clickedViewItem null, so its not valid anymore
I have some javascript running in WebView. In this Javascript code there a function which returns a boolean. I want to check the return value from this function and depends on it hide or not a view in my android code. I tried for one day and it does not work. Do someone knows where is my error? This is my code:
public class MyActivity extends Activity {
private static final String JS_INTERFACE = "Android";
....
webView.getSettings().setJavaScriptEnabled(true);
webView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
webView.loadUrl(getUrl(this.getResources().getString(R.string.host)));
webView.addJavascriptInterface(new WebViewJavaScriptInterface(this), JS_INTERFACE);
webView.setWebViewClient(new WebViewClient(progressBar, this, tvError));
webView.setWebChromeClient(new WebChromeClient(progressBar));
webView.loadUrl("javascript:window.Android.showAdBanner(showSdkAd())");
}
public class WebViewJavaScriptInterface
{
....
#JavascriptInterface
public void showAdBanner(String jsResult) {
if (jsResult == "true") {
((Activity) context).findViewById(R.id.adView).setVisibility(View.GONE);
} else {
((Activity) context).findViewById(R.id.adView).setVisibility(View.GONE);
}
}
}
You're setting the visibility to View.GONE in both cases of the if (jsResult == "true") if statement.
I think the window in the js is unneeded, so
webView.loadUrl("javascript:window.Android.showAdBanner(showSdkAd())");
Should be
webView.loadUrl("javascript:Android.showAdBanner(showSdkAd())");
Also, the javascript callback will be executed in a background thread, so you need to move to the main thread (posting a runnable to a view, runOnUiThread, using a handler etc), before performing Ui operations.
If you have a reference to a View, you can do:
#JavascriptInterface
public void showAdBanner(String jsResult) {
viewReference.post(new Runnable() {
public void run() {
if (jsResult == "true") {
((Activity) context).findViewById(R.id.adView).setVisibility(View.GONE);
} else {
((Activity) context).findViewById(R.id.adView).setVisibility(View.GONE);
}
}
}
Since, you have a reference to the activity, you can replace viewReference.post with ((Activity) context).runOnUiThread
If you initialise a Handler on the main thread, it will be bound to the main thread. As a field of the Activity, you could have:
private Handler mHandler = new Handler();
And then replace viewReference.post with mHandler.post
You could also make a custom Handler that implements handleMessage(Message msg) and then you can just send it an empty message. However, you should read https://techblog.badoo.com/blog/2014/08/28/android-handler-memory-leaks/ to avoid memory issues.
I have started to dig in to C++ and Qt again, and have been mucking around with the WebKit Javascript/Qt bindings. I've got all the moving parts working, with the exception of my QObject subclass being "undefined" on the Javascript side. Here's the simple test app I'm having trouble with:
My main window implementation:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// instantiate a webview
QWebView *webview = new QWebView(this);
webview->setGeometry(0, 0, 400, 300);
webview->setUrl(QUrl("file://localhost/Users/kyle/Sites/tests/qt/index.html"));
// instantiate and attach our QObject
hello *h = new hello();
QWebFrame *frame = webview->page()->mainFrame();
frame->addToJavaScriptWindowObject("Hello", h);
// show the window
webview->show();
}
Hello.cpp
...snip...
QString hello::say()
{
return QString("Kyle");
}
Hello.h
...snip includes...
class hello : public QObject
{
Q_OBJECT
public:
hello();
Q_INVOKABLE QString say();
};
The above-mentioned index.html file does a simple alert(Hello.say()) call, but doing typeof Hello, I get undefined.
I'm a bit rusty with C++, and pretty new to Qt, so I'm sure this is a noob mistake, but I'm stumped.
Objects can't be inserted in the page at any time. You should put that line:
frame->addToJavaScriptWindowObject("Hello", h);
in a slot connected to the javaScriptWindowObjectCleared() signal of the QWebFrame and move some code around, so you can access the frame from that slot.
See also the Form Extractor example included with Qt.
The core of this is really implemented in two methods, which are
shown below:
void MyApi::setWebView( QWebView *view )
{
QWebPage *page = view->page();
frame = page->mainFrame();
attachObject();
connect(frame, &QWebFrame::javaScriptWindowObjectCleared, this, &MyApi::attachObject);
// old approach
//connect( frame, SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(attachObject()) );
}
void MyApi::attachObject()
{
frame->addToJavaScriptWindowObject( QString("MyApi"), this );
}
This code is all that you need in order to make all of the public slots of the
MyApi object visible to javascript. The MyApi class provides two public slots:
public slots:
void doSomething( const QString ¶m );
int doSums( int a, int b );
The first slot simply logs a message to the debug output, the second returns
the sum of its two arguments (yes, slots can return things!). They're called
from javascript like this:
MyApi.doSomething( 'Hello from JS page 2!!!!' );
sum = MyApi.doSums( 2, 3 );
alert( 'C++ says the sum is ' + sum );
The code above was tested in QT5.5, and please note all methods should be put in "public slots" section.